mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +00:00
Compare commits
88 Commits
v0.27.3
...
v0.30.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b26ae86992 | ||
|
|
004f8da0ef | ||
|
|
65f41b3582 | ||
|
|
be67d853aa | ||
|
|
bf233ad3e3 | ||
|
|
45d3eabab9 | ||
|
|
c4f5d58a3e | ||
|
|
582d8dd29c | ||
|
|
abc5388cab | ||
|
|
fd9eb6d877 | ||
|
|
bad8ba225a | ||
|
|
ce2df385a6 | ||
|
|
92b7e445e1 | ||
|
|
332b0a8a1c | ||
|
|
73755b8bfe | ||
|
|
25d90212ce | ||
|
|
d1517d8398 | ||
|
|
7500ad6a83 | ||
|
|
a0159b333e | ||
|
|
22fdb33b4c | ||
|
|
f46f9082f9 | ||
|
|
028f7aa823 | ||
|
|
545bf77326 | ||
|
|
90ac0b269e | ||
|
|
72df5154fc | ||
|
|
4ee03c4528 | ||
|
|
2ef1a5fdf1 | ||
|
|
efb20b1e31 | ||
|
|
ab33f3c49c | ||
|
|
5952c51a39 | ||
|
|
2a9a11bd01 | ||
|
|
79baf9921d | ||
|
|
7e9976efd3 | ||
|
|
5d95610c84 | ||
|
|
bcfe6df24d | ||
|
|
70156cd106 | ||
|
|
e6ef2de40c | ||
|
|
0a78909cf6 | ||
|
|
2155d34779 | ||
|
|
1caef5cc12 | ||
|
|
14910efd4f | ||
|
|
48e0e11063 | ||
|
|
996080c1e9 | ||
|
|
e6aaf91df1 | ||
|
|
b67b930ffc | ||
|
|
a1defadf1e | ||
|
|
01e809315c | ||
|
|
798bf32dec | ||
|
|
622813343f | ||
|
|
65d19f433e | ||
|
|
2d334e4df0 | ||
|
|
f442d6e22a | ||
|
|
d43f6ffdec | ||
|
|
9bea340c44 | ||
|
|
2635e5d8eb | ||
|
|
41ff5729df | ||
|
|
6097432d87 | ||
|
|
5f36a81613 | ||
|
|
2e4ba9984d | ||
|
|
fb275a06fe | ||
|
|
064ea74b6f | ||
|
|
25b642b584 | ||
|
|
f712c07c38 | ||
|
|
83b0aa8f62 | ||
|
|
9780a6aec6 | ||
|
|
b3c0c58c17 | ||
|
|
50687655bf | ||
|
|
26556950d0 | ||
|
|
f72147c4df | ||
|
|
2008dc5b23 | ||
|
|
37664cb19a | ||
|
|
e6b74b690a | ||
|
|
7d2fc83abe | ||
|
|
9febf1e97c | ||
|
|
b53d91e048 | ||
|
|
a5d1112fcd | ||
|
|
d8f0665bdc | ||
|
|
4f6e6e8b77 | ||
|
|
3ce25ff1ef | ||
|
|
c99ac2c5aa | ||
|
|
c9510e8c1d | ||
|
|
4484e96b66 | ||
|
|
9705ff0a24 | ||
|
|
89c832feb0 | ||
|
|
fbead0fb79 | ||
|
|
0f4ef8e781 | ||
|
|
56709b9638 | ||
|
|
2589e56f95 |
@@ -1,6 +1,16 @@
|
||||
root = true
|
||||
|
||||
[*.wxs]
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
tab_width = 4
|
||||
|
||||
[*.{json,wxs,xml}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
21
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
21
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@@ -6,6 +6,27 @@ body:
|
||||
attributes:
|
||||
value: Thanks for taking the time to fill out this bug report!
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |-
|
||||
> [!NOTE]
|
||||
> If you encounter "Counter not found" issues, try to re-build the performance counter first.
|
||||
|
||||
```
|
||||
PS C:\WINDOWS\system32> cd c:\windows\system32
|
||||
PS C:\windows\system32> lodctr /R
|
||||
|
||||
Error: Unable to rebuild performance counter setting from system backup store, error code is 2
|
||||
PS C:\windows\system32> cd ..
|
||||
PS C:\windows> cd syswow64
|
||||
PS C:\windows\syswow64> lodctr /R
|
||||
|
||||
Info: Successfully rebuilt performance counter setting from system backup store
|
||||
PS C:\windows\syswow64> winmgmt.exe /RESYNCPERF
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
|
||||
22
.github/workflows/container_description.yml
vendored
22
.github/workflows/container_description.yml
vendored
@@ -33,25 +33,3 @@ jobs:
|
||||
# Empty string results in README-containers.md being pushed if it
|
||||
# exists. Otherwise, README.md is pushed.
|
||||
readme_file: ''
|
||||
|
||||
PushQuayIoReadme:
|
||||
runs-on: ubuntu-latest
|
||||
name: Push README to quay.io
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- name: Set quay.io org name
|
||||
run: echo "DOCKER_REPO=$(echo quay.io/${GITHUB_REPOSITORY_OWNER} | tr -d '-')" >> $GITHUB_ENV
|
||||
- name: Set quay.io repo name
|
||||
run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
|
||||
- name: Push README to quay.io
|
||||
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
|
||||
env:
|
||||
DOCKER_APIKEY: ${{ secrets.QUAY_IO_API_TOKEN }}
|
||||
with:
|
||||
destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
|
||||
provider: quay
|
||||
# Empty string results in README-containers.md being pushed if it
|
||||
# exists. Otherwise, README.md is pushed.
|
||||
readme_file: ''
|
||||
|
||||
22
.github/workflows/lint.yml
vendored
22
.github/workflows/lint.yml
vendored
@@ -12,6 +12,8 @@ on:
|
||||
- "tools/e2e-output.txt"
|
||||
branches:
|
||||
- master
|
||||
- next
|
||||
- main
|
||||
pull_request:
|
||||
paths:
|
||||
- "go.mod"
|
||||
@@ -21,9 +23,11 @@ on:
|
||||
- "tools/e2e-output.txt"
|
||||
branches:
|
||||
- master
|
||||
- next
|
||||
- main
|
||||
|
||||
env:
|
||||
PROMU_VER: '0.14.0'
|
||||
VERSION_PROMU: '0.14.0'
|
||||
PROMTOOL_VER: '2.43.0'
|
||||
|
||||
jobs:
|
||||
@@ -40,9 +44,9 @@ jobs:
|
||||
|
||||
- name: Install e2e deps
|
||||
run: |
|
||||
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:PROMU_VER)/promu-$($Env:PROMU_VER).windows-amd64.zip -OutFile promu-$($Env:PROMU_VER).windows-amd64.zip
|
||||
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
|
||||
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:VERSION_PROMU)/promu-$($Env:VERSION_PROMU).windows-amd64.zip -OutFile promu-$($Env:VERSION_PROMU).windows-amd64.zip
|
||||
Expand-Archive -Path promu-$($Env:VERSION_PROMU).windows-amd64.zip -DestinationPath .
|
||||
Copy-Item -Path promu-$($Env:VERSION_PROMU).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||
|
||||
# GOPATH\bin dir must be appended to PATH else the `promu` command won't be found
|
||||
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
@@ -64,9 +68,9 @@ jobs:
|
||||
Expand-Archive -Path prometheus-$($Env:PROMTOOL_VER).windows-amd64.zip -DestinationPath .
|
||||
Copy-Item -Path prometheus-$($Env:PROMTOOL_VER).windows-amd64\promtool.exe -Destination "$(go env GOPATH)\bin"
|
||||
|
||||
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:PROMU_VER)/promu-$($Env:PROMU_VER).windows-amd64.zip -OutFile promu-$($Env:PROMU_VER).windows-amd64.zip
|
||||
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
|
||||
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:VERSION_PROMU)/promu-$($Env:VERSION_PROMU).windows-amd64.zip -OutFile promu-$($Env:VERSION_PROMU).windows-amd64.zip
|
||||
Expand-Archive -Path promu-$($Env:VERSION_PROMU).windows-amd64.zip -DestinationPath .
|
||||
Copy-Item -Path promu-$($Env:VERSION_PROMU).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||
|
||||
# GOPATH\bin dir must be appended to PATH else the `promu` command won't be found
|
||||
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
@@ -100,5 +104,5 @@ jobs:
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: v1.59
|
||||
args: "--timeout=5m"
|
||||
version: v1.60
|
||||
args: "--max-same-issues=0"
|
||||
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 "pkg/collector/$PR_TITLE_PREFIX" ]] || [[ -d "$PR_TITLE_PREFIX" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Synchronize common files from prometheus/prometheus" ]]; then
|
||||
if [[ -d "internal/collector/$PR_TITLE_PREFIX" ]] || [[ -d "internal/$PR_TITLE_PREFIX" ]] || [[ -d "pkg/$PR_TITLE_PREFIX" ]] || [[ -d "$PR_TITLE_PREFIX" ]] || [[ "$PR_TITLE_PREFIX" == "docs" ]] || [[ "$PR_TITLE_PREFIX" == "ci" ]] || [[ "$PR_TITLE_PREFIX" == "revert" ]] || [[ "$PR_TITLE_PREFIX" == "fix" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(docs)" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Synchronize common files from prometheus/prometheus" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
55
.github/workflows/release.yml
vendored
55
.github/workflows/release.yml
vendored
@@ -16,7 +16,10 @@ permissions:
|
||||
packages: write
|
||||
|
||||
env:
|
||||
PROMU_VER: '0.14.0'
|
||||
VERSION_PROMU: '0.14.0'
|
||||
VERSION_CONTAINERD: '1.7.21'
|
||||
VERSION_BUILDKIT: '0.15.2'
|
||||
VERSION_BUILDX: '0.16.2'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -24,8 +27,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# fetch-depth required for gitversion in `Build` step
|
||||
fetch-depth: 0
|
||||
fetch-depth: '0'
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
@@ -34,41 +36,38 @@ jobs:
|
||||
# https://github.com/pl4nty/Windows-Containers/blob/Main/helpful_tools/Install-BuildKit-GitHubActions/workflow.yaml
|
||||
- name: Setup containerd
|
||||
run: |
|
||||
$version = "1.7.20"
|
||||
curl.exe -L https://github.com/containerd/containerd/releases/download/v$version/containerd-$version-windows-amd64.tar.gz -o containerd.tar.gz
|
||||
curl.exe -L https://github.com/containerd/containerd/releases/download/v${{ env.VERSION_CONTAINERD }}/containerd-${{ env.VERSION_CONTAINERD }}-windows-amd64.tar.gz -o containerd.tar.gz
|
||||
tar.exe xvf containerd.tar.gz
|
||||
.\bin\containerd.exe --register-service
|
||||
Start-Service containerd
|
||||
- name: Setup BuildKit
|
||||
run: |
|
||||
$version = "v0.15.0"
|
||||
curl.exe -L https://github.com/moby/buildkit/releases/download/$version/buildkit-$version.windows-amd64.tar.gz -o buildkit.tar.gz
|
||||
curl.exe -L https://github.com/moby/buildkit/releases/download/v${{ env.VERSION_BUILDKIT }}/buildkit-v${{ env.VERSION_BUILDKIT }}.windows-amd64.tar.gz -o buildkit.tar.gz
|
||||
tar.exe xvf buildkit.tar.gz
|
||||
|
||||
|
||||
.\bin\buildkitd.exe --register-service
|
||||
Start-Service buildkitd
|
||||
- name: Setup Docker Buildx
|
||||
run: |
|
||||
$version = "v0.16.1"
|
||||
curl.exe -L https://github.com/docker/buildx/releases/download/$version/buildx-$version.windows-amd64.exe -o $env:ProgramData\Docker\cli-plugins\docker-buildx.exe
|
||||
curl.exe -L https://github.com/docker/buildx/releases/download/v${{ env.VERSION_BUILDX }}/buildx-v${{ env.VERSION_BUILDX }}.windows-amd64.exe -o $env:ProgramData\Docker\cli-plugins\docker-buildx.exe
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver: remote
|
||||
endpoint: npipe:////./pipe/buildkitd
|
||||
|
||||
- name: Install WiX
|
||||
run: dotnet tool install --global wix
|
||||
|
||||
- name: Install WiX extensions
|
||||
run: |
|
||||
wix extension add -g WixToolset.Util.wixext
|
||||
wix extension add -g WixToolset.Ui.wixext
|
||||
wix extension add -g WixToolset.Firewall.wixext
|
||||
|
||||
- name: Install Build deps
|
||||
run: |
|
||||
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:PROMU_VER)/promu-$($Env:PROMU_VER).windows-amd64.zip -OutFile promu-$($Env:PROMU_VER).windows-amd64.zip
|
||||
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
|
||||
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:VERSION_PROMU)/promu-$($Env:VERSION_PROMU).windows-amd64.zip -OutFile promu-$($Env:VERSION_PROMU).windows-amd64.zip
|
||||
Expand-Archive -Path promu-$($Env:VERSION_PROMU).windows-amd64.zip -DestinationPath .
|
||||
Copy-Item -Path promu-$($Env:VERSION_PROMU).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||
|
||||
# GOPATH\bin dir must be added to PATH else the `promu` commands won't be found
|
||||
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
@@ -76,49 +75,51 @@ jobs:
|
||||
- name: Build
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
|
||||
$Version = git describe --tags --always
|
||||
$Version = $Version -replace 'v', ''
|
||||
# '+' symbols are invalid characters in image tags
|
||||
$Version = $Version -replace '\+', '_'
|
||||
$Version | Set-Content VERSION -PassThru
|
||||
|
||||
|
||||
make build-all
|
||||
|
||||
|
||||
# GH requires all files to have different names, so add version/arch to differentiate
|
||||
foreach($Arch in "amd64", "arm64") {
|
||||
Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe
|
||||
}
|
||||
|
||||
Get-ChildItem -Path output
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows_exporter_binaries
|
||||
path: output\windows_exporter-*.exe
|
||||
Get-ChildItem -Path output
|
||||
|
||||
- name: Build Release Artifacts
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Version = Get-Content VERSION
|
||||
|
||||
|
||||
foreach($Arch in "amd64", "arm64") {
|
||||
Write-Host "Building windows_exporter $Version msi for $Arch"
|
||||
.\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch"
|
||||
}
|
||||
|
||||
|
||||
Move-Item installer\*.msi output\
|
||||
Get-ChildItem -Path output\
|
||||
|
||||
promu checksum output\
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows_exporter_binaries
|
||||
path: |
|
||||
output\windows_exporter-*.exe
|
||||
output\windows_exporter-*.msi
|
||||
|
||||
- name: Build Docker Artifacts
|
||||
run: make build-all
|
||||
env:
|
||||
VERSION: >-
|
||||
${{
|
||||
startsWith(github.ref, 'refs/tags/') && 'latest' ||
|
||||
startsWith(github.ref, 'refs/tags/') && 'latest' ||
|
||||
(
|
||||
github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || github.ref_name
|
||||
)
|
||||
|
||||
2
.github/workflows/spelling.yml
vendored
2
.github/workflows/spelling.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- master
|
||||
|
||||
env:
|
||||
PROMU_VER: 'v0.14.0'
|
||||
VERSION_PROMU: 'v0.14.0'
|
||||
|
||||
jobs:
|
||||
codespell:
|
||||
|
||||
29
.github/workflows/stale-close.yml
vendored
Normal file
29
.github/workflows/stale-close.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
jobs:
|
||||
stale:
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# opt out of defaults to avoid marking issues as stale and closing them
|
||||
# https://github.com/actions/stale#days-before-close
|
||||
# https://github.com/actions/stale#days-before-stale
|
||||
days-before-stale: -1
|
||||
days-before-close: -1
|
||||
stale-pr-message: ''
|
||||
stale-issue-message: 'This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.'
|
||||
operations-per-run: 30
|
||||
# override days-before-stale, for only marking the pull requests as stale
|
||||
days-before-issue-stale: 90
|
||||
days-before-issue-close: 30
|
||||
stale-pr-label: stale
|
||||
exempt-pr-labels: keepalive
|
||||
32
.github/workflows/stale.yml
vendored
32
.github/workflows/stale.yml
vendored
@@ -1,21 +1,31 @@
|
||||
name: 'Close stale issues and PRs'
|
||||
name: Stale Check
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
- cron: '16 22 * * *'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||
with:
|
||||
stale-issue-message: 'This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.'
|
||||
exempt-issue-labels: 'lifecycle/frozen'
|
||||
days-before-stale: 90
|
||||
days-before-close: 30
|
||||
enable-statistics: false
|
||||
operations-per-run: 500
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# opt out of defaults to avoid marking issues as stale and closing them
|
||||
# https://github.com/actions/stale#days-before-close
|
||||
# https://github.com/actions/stale#days-before-stale
|
||||
days-before-stale: -1
|
||||
days-before-close: -1
|
||||
# Setting it to empty string to skip comments.
|
||||
# https://github.com/actions/stale#stale-pr-message
|
||||
# https://github.com/actions/stale#stale-issue-message
|
||||
stale-pr-message: ''
|
||||
stale-issue-message: ''
|
||||
operations-per-run: 30
|
||||
# override days-before-stale, for only marking the pull requests as stale
|
||||
days-before-pr-stale: 60
|
||||
stale-pr-label: stale
|
||||
exempt-pr-labels: keepalive
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- containedctx
|
||||
- contextcheck
|
||||
- cyclop
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- err113
|
||||
- execinquery
|
||||
- exhaustive
|
||||
- exhaustruct
|
||||
- exportloopref
|
||||
- fatcontext
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gocognit
|
||||
- goconst
|
||||
- gocyclo
|
||||
- godox
|
||||
- inamedparam
|
||||
- ireturn
|
||||
- godot
|
||||
- gomnd
|
||||
- paralleltest
|
||||
- lll
|
||||
- maintidx
|
||||
- mnd
|
||||
- nlreturn
|
||||
- noctx
|
||||
- testpackage
|
||||
- varnamelen
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- execinquery
|
||||
- gomnd
|
||||
- stylecheck
|
||||
- maintidx
|
||||
|
||||
run:
|
||||
timeout: 5m
|
||||
|
||||
linters-settings:
|
||||
gosec:
|
||||
excludes:
|
||||
- G101 # Potential hardcoded credentials
|
||||
- G115 # integer overflow conversion
|
||||
|
||||
gci:
|
||||
sections:
|
||||
- prefix(github.com/prometheus-community/windows_exporter/pkg/initiate)
|
||||
- prefix(github.com/prometheus-community/windows_exporter/internal/initiate)
|
||||
- standard # Standard section: captures all standard packages.
|
||||
- default # Default section: contains all imports that could not be matched to another section type.
|
||||
custom-order: true
|
||||
@@ -47,7 +48,30 @@ linters-settings:
|
||||
# Support string case: `camel`, `pascal`, `kebab`, `snake`, `upperSnake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`, `header`
|
||||
json: camel
|
||||
yaml: snake
|
||||
|
||||
forbidigo:
|
||||
forbid:
|
||||
- "^(fmt\\.Print(|f|ln)|print|println)$"
|
||||
- p: "^syscall\\.(.{1,7}|.{7}[^N]|.{9,})$"
|
||||
msg: use golang.org/x/sys/windows instead of syscall
|
||||
- p: "^windows\\.NewLazyDLL$"
|
||||
msg: use NewLazySystemDLL instead NewLazyDLL
|
||||
sloglint:
|
||||
no-mixed-args: true
|
||||
kv-only: false
|
||||
attr-only: true
|
||||
no-global: "all"
|
||||
context: "scope"
|
||||
static-msg: false
|
||||
no-raw-keys: false
|
||||
key-naming-case: snake
|
||||
forbidden-keys:
|
||||
- time
|
||||
- level
|
||||
- msg
|
||||
- source
|
||||
args-on-sep-lines: true
|
||||
stylecheck:
|
||||
checks: ["all", "-ST1003"]
|
||||
issues:
|
||||
exclude:
|
||||
- don't use underscores in Go names
|
||||
@@ -61,3 +85,7 @@ issues:
|
||||
- text: "don't use ALL_CAPS in Go names; use CamelCase"
|
||||
linters:
|
||||
- revive
|
||||
- path: internal/perfdata/v1/
|
||||
linters:
|
||||
- godox
|
||||
- stylecheck
|
||||
|
||||
35
.promu.yml
35
.promu.yml
@@ -1,19 +1,26 @@
|
||||
go:
|
||||
version: 1.20
|
||||
# Whenever the Go version is updated here,
|
||||
# .github/workflows should also be updated.
|
||||
version: 1.23
|
||||
cgo: false
|
||||
repository:
|
||||
path: github.com/prometheus-community/windows_exporter
|
||||
path: github.com/prometheus-community/windows_exporter
|
||||
build:
|
||||
binaries:
|
||||
- name: windows_exporter
|
||||
ldflags: |
|
||||
-X github.com/prometheus/common/version.Version={{.Version}}
|
||||
-X github.com/prometheus/common/version.Revision={{.Revision}}
|
||||
-X github.com/prometheus/common/version.Branch={{.Branch}}
|
||||
-X github.com/prometheus/common/version.BuildUser={{user}}@{{host}}
|
||||
-X github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}}
|
||||
binaries:
|
||||
- name: windows_exporter
|
||||
tags:
|
||||
all:
|
||||
- trimpath
|
||||
ldflags: |
|
||||
-X github.com/prometheus/common/version.Version={{.Version}}
|
||||
-X github.com/prometheus/common/version.Revision={{.Revision}}
|
||||
-X github.com/prometheus/common/version.Branch={{.Branch}}
|
||||
-X github.com/prometheus/common/version.BuildUser={{user}}@{{host}}
|
||||
-X github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}}
|
||||
tarball:
|
||||
files:
|
||||
- LICENSE
|
||||
files:
|
||||
- LICENSE
|
||||
crossbuild:
|
||||
platforms:
|
||||
- windows
|
||||
platforms:
|
||||
- windows/amd64
|
||||
- windows/arm64
|
||||
|
||||
4
Makefile
4
Makefile
@@ -7,7 +7,7 @@ DOCKER_REPO ?= prometheuscommunity
|
||||
DOCKER_IMAGE_NAME ?= windows-exporter
|
||||
|
||||
# ALL_DOCKER_REPOS is the list of repositories to push the image to. ghcr.io requires that org name be the same as the image repo name.
|
||||
ALL_DOCKER_REPOS ?= docker.io/$(DOCKER_REPO) ghcr.io/prometheus-community # quay.io/$(DOCKER_REPO)
|
||||
ALL_DOCKER_REPOS ?= docker.io/$(DOCKER_REPO) ghcr.io/prometheus-community # quay.io/$(DOCKER_REPO)
|
||||
|
||||
# Image Variables for host process Container
|
||||
# Windows image build is heavily influenced by https://github.com/kubernetes/kubernetes/blob/master/cluster/images/etcd/Makefile
|
||||
@@ -29,7 +29,7 @@ test:
|
||||
go test -v ./...
|
||||
|
||||
bench:
|
||||
go test -v -bench='benchmarkcollector' ./pkg/collector/{cpu,logical_disk,physical_disk,logon,memory,net,printer,process,service,system,tcp,time}
|
||||
go test -v -bench='benchmarkcollector' ./internal/collectors/{cpu,logical_disk,physical_disk,logon,memory,net,printer,process,service,system,tcp,time}
|
||||
|
||||
lint:
|
||||
golangci-lint -c .golangci.yaml run
|
||||
|
||||
127
README.md
127
README.md
@@ -14,39 +14,30 @@ Name | Description | Enabled by default
|
||||
[cache](docs/collector.cache.md) | Cache metrics |
|
||||
[cpu](docs/collector.cpu.md) | CPU usage | ✓
|
||||
[cpu_info](docs/collector.cpu_info.md) | CPU Information |
|
||||
[cs](docs/collector.cs.md) | "Computer System" metrics (system properties, num cpus/total memory) | ✓
|
||||
[cs](docs/collector.cs.md) | "Computer System" metrics (system properties, num cpus/total memory) |
|
||||
[container](docs/collector.container.md) | Container metrics |
|
||||
[diskdrive](docs/collector.diskdrive.md) | Diskdrive metrics |
|
||||
[dfsr](docs/collector.dfsr.md) | DFSR metrics |
|
||||
[dhcp](docs/collector.dhcp.md) | DHCP Server |
|
||||
[dns](docs/collector.dns.md) | DNS Server |
|
||||
[exchange](docs/collector.exchange.md) | Exchange metrics |
|
||||
[filetime](docs/collector.filetime.md) | FileTime metrics |
|
||||
[fsrmquota](docs/collector.fsrmquota.md) | Microsoft File Server Resource Manager (FSRM) Quotas collector |
|
||||
[hyperv](docs/collector.hyperv.md) | Hyper-V hosts |
|
||||
[iis](docs/collector.iis.md) | IIS sites and applications |
|
||||
[license](docs/collector.license.md) | Windows license status |
|
||||
[license](docs/collector.license.md) | Windows license status |
|
||||
[logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | ✓
|
||||
[logon](docs/collector.logon.md) | User logon sessions |
|
||||
[memory](docs/collector.memory.md) | Memory usage metrics |
|
||||
[mscluster_cluster](docs/collector.mscluster_cluster.md) | MSCluster cluster metrics |
|
||||
[mscluster_network](docs/collector.mscluster_network.md) | MSCluster network metrics |
|
||||
[mscluster_node](docs/collector.mscluster_node.md) | MSCluster Node metrics |
|
||||
[mscluster_resource](docs/collector.mscluster_resource.md) | MSCluster Resource metrics |
|
||||
[mscluster_resourcegroup](docs/collector.mscluster_resourcegroup.md) | MSCluster ResourceGroup metrics |
|
||||
[memory](docs/collector.memory.md) | Memory usage metrics | ✓
|
||||
[mscluster](docs/collector.mscluster.md) | MSCluster metrics |
|
||||
[msmq](docs/collector.msmq.md) | MSMQ queues |
|
||||
[mssql](docs/collector.mssql.md) | [SQL Server Performance Objects](https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/use-sql-server-objects#SQLServerPOs) metrics |
|
||||
[netframework_clrexceptions](docs/collector.netframework_clrexceptions.md) | .NET Framework CLR Exceptions |
|
||||
[netframework_clrinterop](docs/collector.netframework_clrinterop.md) | .NET Framework Interop Metrics |
|
||||
[netframework_clrjit](docs/collector.netframework_clrjit.md) | .NET Framework JIT metrics |
|
||||
[netframework_clrloading](docs/collector.netframework_clrloading.md) | .NET Framework CLR Loading metrics |
|
||||
[netframework_clrlocksandthreads](docs/collector.netframework_clrlocksandthreads.md) | .NET Framework locks and metrics threads |
|
||||
[netframework_clrmemory](docs/collector.netframework_clrmemory.md) | .NET Framework Memory metrics |
|
||||
[netframework_clrremoting](docs/collector.netframework_clrremoting.md) | .NET Framework Remoting metrics |
|
||||
[netframework_clrsecurity](docs/collector.netframework_clrsecurity.md) | .NET Framework Security Check metrics |
|
||||
[netframework](docs/collector.netframework.md) | .NET Framework metrics |
|
||||
[net](docs/collector.net.md) | Network interface I/O | ✓
|
||||
[os](docs/collector.os.md) | OS metrics (memory, processes, users) | ✓
|
||||
[perfdata](docs/collector.perfdata.md) | Custom perfdata metrics |
|
||||
[physical_disk](docs/collector.physical_disk.md) | physical disk metrics | ✓
|
||||
[printer](docs/collector.printer.md) | Printer metrics |
|
||||
[printer](docs/collector.printer.md) | Printer metrics |
|
||||
[process](docs/collector.process.md) | Per-process metrics |
|
||||
[remote_fx](docs/collector.remote_fx.md) | RemoteFX protocol (RDP) metrics |
|
||||
[scheduled_task](docs/collector.scheduled_task.md) | Scheduled Tasks metrics |
|
||||
@@ -56,12 +47,11 @@ Name | Description | Enabled by default
|
||||
[smtp](docs/collector.smtp.md) | IIS SMTP Server |
|
||||
[system](docs/collector.system.md) | System calls | ✓
|
||||
[tcp](docs/collector.tcp.md) | TCP connections |
|
||||
[teradici_pcoip](docs/collector.teradici_pcoip.md) | [Teradici PCoIP](https://www.teradici.com/web-help/pcoip_wmi_specs/) session metrics |
|
||||
[time](docs/collector.time.md) | Windows Time Service |
|
||||
[thermalzone](docs/collector.thermalzone.md) | Thermal information
|
||||
[terminal_services](docs/collector.terminal_services.md) | Terminal services (RDS)
|
||||
[textfile](docs/collector.textfile.md) | Read prometheus metrics from a text file |
|
||||
[vmware_blast](docs/collector.vmware_blast.md) | VMware Blast session metrics |
|
||||
[thermalzone](docs/collector.thermalzone.md) | Thermal information |
|
||||
[time](docs/collector.time.md) | Windows Time Service |
|
||||
[update](docs/collector.update.md) | Windows Update Service |
|
||||
[vmware](docs/collector.vmware.md) | Performance counters installed by the Vmware Guest agent |
|
||||
|
||||
See the linked documentation on each collector for more information on reported metrics, configuration settings and usage examples.
|
||||
@@ -85,77 +75,90 @@ This can be useful for having different Prometheus servers collect specific metr
|
||||
|
||||
windows_exporter accepts flags to configure certain behaviours. The ones configuring the global behaviour of the exporter are listed below, while collector-specific ones are documented in the respective collector documentation above.
|
||||
|
||||
| Flag | Description | Default value |
|
||||
|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
||||
| `--web.listen-address` | host:port for exporter. | `:9182` |
|
||||
| `--telemetry.path` | URL path for surfacing collected metrics. | `/metrics` |
|
||||
| `--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5` |
|
||||
| `--collectors.enabled` | Comma-separated list of collectors to use. Use `[defaults]` as a placeholder which gets expanded containing all the collectors enabled by default." | `[defaults]` |
|
||||
| `--collectors.print` | If true, print available collectors and exit. | |
|
||||
| `--scrape.timeout-margin` | Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads. | `0.5` |
|
||||
| `--web.config.file` | A [web config][web_config] for setting up TLS and Auth | None |
|
||||
| `--config.file` | [Using a config file](#using-a-configuration-file) from path or URL | None |
|
||||
| `--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false |
|
||||
| Flag | Description | Default value |
|
||||
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
||||
| `--web.listen-address` | host:port for exporter. | `:9182` |
|
||||
| `--telemetry.path` | URL path for surfacing collected metrics. | `/metrics` |
|
||||
| `--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5` |
|
||||
| `--collectors.enabled` | Comma-separated list of collectors to use. Use `[defaults]` as a placeholder which gets expanded containing all the collectors enabled by default." | `[defaults]` |
|
||||
| `--collectors.print` | If true, print available collectors and exit. | |
|
||||
| `--scrape.timeout-margin` | Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads. | `0.5` |
|
||||
| `--web.config.file` | A [web config][web_config] for setting up TLS and Auth | None |
|
||||
| `--config.file` | [Using a config file](#using-a-configuration-file) from path or URL | None |
|
||||
| `--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false |
|
||||
| `--log.file` | Output file of log messages. One of [stdout, stderr, eventlog, \<path to log file>]<br>**NOTE:** The MSI installer will add a default argument to the installed service setting this to eventlog | stderr |
|
||||
|
||||
## Installation
|
||||
|
||||
The latest release can be downloaded from the [releases page](https://github.com/prometheus-community/windows_exporter/releases).
|
||||
|
||||
Each release provides a .msi installer. The installer will setup the windows_exporter as a Windows service, as well as create an exception in the Windows Firewall.
|
||||
|
||||
If the installer is run without any parameters, the exporter will run with default settings for enabled collectors, ports, etc. The following parameters are available:
|
||||
If the installer is run without any parameters, the exporter will run with default settings for enabled collectors, ports, etc.
|
||||
|
||||
| Name | Description |
|
||||
|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `ENABLED_COLLECTORS` | As the `--collectors.enabled` flag, provide a comma-separated list of enabled collectors |
|
||||
| `LISTEN_ADDR` | The IP address to bind to. Defaults to an empty string. (any local address) |
|
||||
| `LISTEN_PORT` | The port to bind to. Defaults to `9182`. |
|
||||
| `METRICS_PATH` | The path at which to serve metrics. Defaults to `/metrics` |
|
||||
| `TEXTFILE_DIRS` | As the `--collector.textfile.directories` flag, provide a directory to read text files with metrics from |
|
||||
| `REMOTE_ADDR` | Allows setting comma separated remote IP addresses for the Windows Firewall exception (allow list). Defaults to an empty string (any remote address). |
|
||||
| `EXTRA_FLAGS` | Allows passing full CLI flags. Defaults to an empty string. |
|
||||
| `ADD_FIREWALL_EXCEPTION` | Setup an firewall exception for windows_exporter. Defaults to `yes`. |
|
||||
| `ENABLE_V1_PERFORMANCE_COUNTERS` | Enables V1 performance counter on modern systems. Defaults to `yes`. |
|
||||
The installer provides a configuration file to customize the exporter.
|
||||
|
||||
Parameters are sent to the installer via `msiexec`. Example invocations:
|
||||
The configuration file
|
||||
* is located in the same directory as the exporter executable.
|
||||
* has the YAML format and is provided with the `--config.file` parameter.
|
||||
* can be used to enable or disable collectors, set collector-specific parameters, and set global parameters.
|
||||
|
||||
The following parameters are available:
|
||||
|
||||
| Name | Description |
|
||||
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `ENABLED_COLLECTORS` | As the `--collectors.enabled` flag, provide a comma-separated list of enabled collectors |
|
||||
| `CONFIG_FILE` | Use the `--config.file` flag to specify a config file. If empty, no config file will be set. The special value `config.yaml` set the path to the config.yaml at install dir | |
|
||||
| `LISTEN_ADDR` | The IP address to bind to. Defaults to an empty string. (any local address) |
|
||||
| `LISTEN_PORT` | The port to bind to. Defaults to `9182`. |
|
||||
| `METRICS_PATH` | The path at which to serve metrics. Defaults to `/metrics` |
|
||||
| `TEXTFILE_DIRS` | Use the `--collector.textfile.directories` flag to specify one or more directories, separated by commas, where the collector should read text files containing metrics |
|
||||
| `REMOTE_ADDR` | Allows setting comma separated remote IP addresses for the Windows Firewall exception (allow list). Defaults to an empty string (any remote address). |
|
||||
| `EXTRA_FLAGS` | Allows passing full CLI flags. Defaults to an empty string. For `--collectors.enabled` and `--config.file`, use the specialized properties `ENABLED_COLLECTORS` and `CONFIG_FILE` |
|
||||
| `ADDLOCAL` | Enables features within the windows_exporter installer. Supported values: `FirewallException` |
|
||||
| `REMOVE` | Disables features within the windows_exporter installer. Supported values: `FirewallException` |
|
||||
|
||||
Parameters are sent to the installer via `msiexec`.
|
||||
On PowerShell, the `--%` should be passed before defining properties.
|
||||
|
||||
Example invocations:
|
||||
|
||||
```powershell
|
||||
msiexec /i <path-to-msi-file> ENABLED_COLLECTORS=os,iis LISTEN_PORT=5000
|
||||
msiexec /i <path-to-msi-file> --% ENABLED_COLLECTORS=os,iis LISTEN_PORT=5000
|
||||
```
|
||||
|
||||
Example service collector with a custom query.
|
||||
```powershell
|
||||
msiexec /i <path-to-msi-file> ENABLED_COLLECTORS=os,service --% EXTRA_FLAGS="--collector.service.services-where ""Name LIKE 'sql%'"""
|
||||
msiexec /i <path-to-msi-file> --% ENABLED_COLLECTORS=os,service EXTRA_FLAGS="--collectors.exchange.enabled=""ADAccessProcesses"""
|
||||
```
|
||||
|
||||
Define a config file.
|
||||
```powershell
|
||||
msiexec /i <path-to-msi-file> --% CONFIG_FILE="D:\config.yaml"
|
||||
```
|
||||
|
||||
On some older versions of Windows,
|
||||
you may need to surround parameter values with double quotes to get the installation command parsing properly:
|
||||
```powershell
|
||||
msiexec /i C:\Users\Administrator\Downloads\windows_exporter.msi ENABLED_COLLECTORS="ad,iis,logon,memory,process,tcp,textfile,thermalzone" TEXTFILE_DIRS="C:\custom_metrics\"
|
||||
msiexec /i C:\Users\Administrator\Downloads\windows_exporter.msi --% ENABLED_COLLECTORS="ad,iis,logon,memory,process,tcp,textfile,thermalzone" TEXTFILE_DIRS="C:\custom_metrics\"
|
||||
```
|
||||
|
||||
To install the exporter with creating a firewall exception, use the following command:
|
||||
|
||||
```powershell
|
||||
msiexec /i <path-to-msi-file> ADD_FIREWALL_EXCEPTION=yes
|
||||
msiexec /i <path-to-msi-file> --% ADDLOCAL=FirewallException
|
||||
```
|
||||
|
||||
To repair an installation, e.g force re-creating Windows service:
|
||||
|
||||
```powershell
|
||||
msiexec /fa <path-to-msi-file>
|
||||
```
|
||||
|
||||
|
||||
Powershell versions 7.3 and above require [PSNativeCommandArgumentPassing](https://learn.microsoft.com/en-us/powershell/scripting/learn/experimental-features?view=powershell-7.3) to be set to `Legacy` when using `--% EXTRA_FLAGS`:
|
||||
PowerShell versions 7.3 and above require [PSNativeCommandArgumentPassing](https://learn.microsoft.com/en-us/powershell/scripting/learn/experimental-features?view=powershell-7.3) to be set to `Legacy` when using `--% EXTRA_FLAGS`:
|
||||
|
||||
```powershell
|
||||
$PSNativeCommandArgumentPassing = 'Legacy'
|
||||
msiexec /i <path-to-msi-file> ENABLED_COLLECTORS=os,service --% EXTRA_FLAGS="--collector.service.services-where ""Name LIKE 'sql%'"""
|
||||
msiexec /i <path-to-msi-file> ENABLED_COLLECTORS=os,service --% EXTRA_FLAGS="--collectors.exchange.enabled=""ADAccessProcesses"""
|
||||
```
|
||||
|
||||
## Docker Implementation
|
||||
|
||||
The windows_exporter can be run as a Docker container. The Docker image is available on
|
||||
The windows_exporter can be run as a Docker container. The Docker image is available on
|
||||
|
||||
* [Docker Hub](https://hub.docker.com/r/prometheuscommunity/windows-exporter): `docker.io/prometheuscommunity/windows-exporter`
|
||||
* [GitHub Container Registry](https://github.com/prometheus-community/windows_exporter/pkgs/container/windows-exporter): `ghcr.io/prometheus-community/windows-exporter`
|
||||
@@ -192,7 +195,7 @@ The prometheus metrics will be exposed on [localhost:9182](http://localhost:9182
|
||||
|
||||
### Enable only service collector and specify a custom query
|
||||
|
||||
.\windows_exporter.exe --collectors.enabled "service" --collector.service.services-where "Name='windows_exporter'"
|
||||
.\windows_exporter.exe --collectors.enabled "service" --collector.service.include="windows_exporter"
|
||||
|
||||
### Enable only process collector and specify a custom query
|
||||
|
||||
@@ -218,10 +221,10 @@ If you need to skip TLS verification, you can use the `--config.file.insecure-sk
|
||||
|
||||
```yaml
|
||||
collectors:
|
||||
enabled: cpu,cs,net,service
|
||||
enabled: cpu,net,service
|
||||
collector:
|
||||
service:
|
||||
services-where: "Name='windows_exporter'"
|
||||
include: windows_exporter
|
||||
log:
|
||||
level: warn
|
||||
```
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# example configuration file for windows_exporter
|
||||
|
||||
collectors:
|
||||
enabled: cpu,cpu_info,cs,exchange,iis,logical_disk,logon,memory,net,os,process,remote_fx,service,system,tcp,time,terminal_services,textfile
|
||||
enabled: cpu,cpu_info,exchange,iis,logical_disk,logon,memory,net,os,process,remote_fx,service,system,tcp,time,terminal_services,textfile
|
||||
collector:
|
||||
service:
|
||||
services-where: "Name='windows_exporter'"
|
||||
include: "windows_exporter"
|
||||
log:
|
||||
level: warn
|
||||
level: warn
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
{{ template "head" . }}
|
||||
|
||||
{{ template "prom_content_head" . }}
|
||||
<h1>Node Overview - {{ reReplaceAll "(.*?://)([^:/]+?)(:\\d+)?/.*" "$2" .Params.instance }}</h1>
|
||||
|
||||
<h3>CPU Usage</h3>
|
||||
<div id="cpuGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#cpuGraph"),
|
||||
expr: "sum by (mode)(irate(windows_cpu_time_total{job='node',instance='{{ .Params.instance }}',mode!='idle'}[5m]))",
|
||||
renderer: 'area',
|
||||
max: {{ with printf "count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance | query }}{{ . | first | value }}{{ else}}undefined{{end}},
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yTitle: 'Cores'
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Network Utilization</h3>
|
||||
<div id="networkioGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#networkioGraph"),
|
||||
expr: [
|
||||
"irate(windows_net_bytes_sent_total{job='node',instance='{{ .Params.instance }}',nic!~'^isatap_ec2_internal'}[5m])",
|
||||
"irate(windows_net_bytes_received_total{job='node',instance='{{ .Params.instance }}',nic!~'^isatap_ec2_internal'}[5m])",
|
||||
],
|
||||
min: 0,
|
||||
name: [ 'sent', 'received' ],
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yUnits: "B",
|
||||
yTitle: 'Network IO'
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Disk I/O Utilization</h3>
|
||||
<div id="diskioGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#diskioGraph"),
|
||||
expr: [
|
||||
"100 - irate(windows_logical_disk_idle_seconds_total{job='node',instance='{{ .Params.instance }}',volume!~'^HarddiskVolume.*$'}[5m]) * 100",
|
||||
],
|
||||
min: 0,
|
||||
name: '[[ volume ]]',
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yUnits: "%",
|
||||
yTitle: 'Disk I/O Utilization'
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Memory</h3>
|
||||
<div id="memoryGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#memoryGraph"),
|
||||
renderer: 'area',
|
||||
expr: [
|
||||
"windows_cs_physical_memory_bytes{job='node',instance='{{ .Params.instance }}'}",
|
||||
"windows_os_physical_memory_free_bytes{job='node',instance='{{ .Params.instance }}'}",
|
||||
"windows_cs_physical_memory__bytes{job='node',instance='{{ .Params.instance }}'} - windows_os_physical_memory_free_bytes{job='node',instance='{{.Params.instance}}'}",
|
||||
"windows_os_virtual_memory_bytes{job='node',instance='{{ .Params.instance }}'}",
|
||||
],
|
||||
name: ["Physical", "Free", "Used", "Virtual"],
|
||||
min: 0,
|
||||
yUnits: "B",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize1024,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize1024,
|
||||
yTitle: 'Memory'
|
||||
})
|
||||
</script>
|
||||
|
||||
{{ template "prom_right_table_head" }}
|
||||
<tr><th colspan="2">Overview</th></tr>
|
||||
<tr>
|
||||
<td>User CPU</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "sum(irate(windows_cpu_time_total{job='node',instance='%s',mode='user'}[5m])) * 100 / count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance .Params.instance) "%" "printf.1f") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privileged CPU</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "sum(irate(windows_cpu_time_total{job='node',instance='%s',mode='privileged'}[5m])) * 100 / count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance .Params.instance) "%" "printf.1f") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory Total</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "windows_cs_physical_memory_bytes{job='node',instance='%s'}" .Params.instance) "B" "humanize1024") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory Free</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "windows_os_physical_memory_free_bytes{job='node',instance='%s'}" .Params.instance) "B" "humanize1024") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">Network</th>
|
||||
</tr>
|
||||
{{ range printf "windows_net_bytes_received_total{job='node',instance='%s',nic!='isatap_ec2_internal'}" .Params.instance | query | sortByLabel "nic" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.nic }} Received</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_net_bytes_received_total{job='node',instance='%s',nic='%s'}[5m])" .Labels.instance .Labels.nic) "B/s" "humanize") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ .Labels.nic }} Transmitted</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_net_bytes_sent_total{job='node',instance='%s',nic='%s'}[5m])" .Labels.instance .Labels.nic) "B/s" "humanize") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">Disks</th>
|
||||
</tr>
|
||||
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.volume }} Utilization</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "100 - irate(windows_logical_disk_idle_seconds_total{job='node',instance='%s',volume='%s'}[5m]) * 100" .Labels.instance .Labels.volume) "%" "printf.1f") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.volume }} Throughput</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_logical_disk_read_bytes_total{job='node',instance='%s',volume='%s'}[5m]) + irate(windows_logical_disk_write_bytes_total{job='node',instance='%s',volume='%s'}[5m])" .Labels.instance .Labels.volume .Labels.instance .Labels.volume) "B/s" "humanize") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
<tr>
|
||||
<th colspan="2">Filesystem Fullness</th>
|
||||
</tr>
|
||||
{{ define "roughlyNearZero" }}
|
||||
{{ if gt .1 . }}~0{{ else }}{{ printf "%.1f" . }}{{ end }}
|
||||
{{ end }}
|
||||
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.volume }}</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "100 - windows_logical_disk_free_bytes{job='node',instance='%s',volume='%s'} / windows_logical_disk_size_bytes{job='node'} * 100" .Labels.instance .Labels.volume) "%" "roughlyNearZero") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tr>
|
||||
{{ template "prom_right_table_tail" }}
|
||||
|
||||
{{ template "prom_content_tail" . }}
|
||||
|
||||
{{ template "tail" }}
|
||||
@@ -21,22 +21,11 @@ This directory contains documentation of the collectors in the windows_exporter,
|
||||
- [`logical_disk`](collector.logical_disk.md)
|
||||
- [`logon`](collector.logon.md)
|
||||
- [`memory`](collector.memory.md)
|
||||
- [`mscluster_cluster`](collector.mscluster_cluster.md)
|
||||
- [`mscluster_network`](collector.mscluster_network.md)
|
||||
- [`mscluster_node`](collector.mscluster_node.md)
|
||||
- [`mscluster_resource`](collector.mscluster_resource.md)
|
||||
- [`mscluster_resourcegroup`](collector.mscluster_resourcegroup.md)
|
||||
- [`mscluster`](collector.mscluster.md)
|
||||
- [`msmq`](collector.msmq.md)
|
||||
- [`mssql`](collector.mssql.md)
|
||||
- [`net`](collector.net.md)
|
||||
- [`netframework_clrexceptions`](collector.netframework_clrexceptions.md)
|
||||
- [`netframework_clrinterop`](collector.netframework_clrinterop.md)
|
||||
- [`netframework_clrjit`](collector.netframework_clrjit.md)
|
||||
- [`netframework_clrloading`](collector.netframework_clrloading.md)
|
||||
- [`netframework_clrlocksandthreads`](collector.netframework_clrlocksandthreads.md)
|
||||
- [`netframework_clrmemory`](collector.netframework_clrmemory.md)
|
||||
- [`netframework_clrremoting`](collector.netframework_clrremoting.md)
|
||||
- [`netframework_clrsecurity`](collector.netframework_clrsecurity.md)
|
||||
- [`netframework`](collector.netframework.md)
|
||||
- [`nps`](collector.nps.md)
|
||||
- [`os`](collector.os.md)
|
||||
- [`physical_disk`](collector.physical_disk.md)
|
||||
@@ -48,10 +37,9 @@ This directory contains documentation of the collectors in the windows_exporter,
|
||||
- [`smtp`](collector.smtp.md)
|
||||
- [`system`](collector.system.md)
|
||||
- [`tcp`](collector.tcp.md)
|
||||
- [`teradici_pcoip`](collector.teradici_pcoip.md)
|
||||
- [`terminal_services`](collector.terminal_services.md)
|
||||
- [`textfile`](collector.textfile.md)
|
||||
- [`thermalzone`](collector.thermalzone.md)
|
||||
- [`time`](collector.time.md)
|
||||
- [`update`](collector.update.md)
|
||||
- [`vmware`](collector.vmware.md)
|
||||
- [`vmware_blast`](collector.vmware_blast.md)
|
||||
|
||||
@@ -16,26 +16,22 @@ None
|
||||
## Metrics
|
||||
These metrics are available on all versions of Windows:
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_cpu_cstate_seconds_total` | Time spent in low-power idle states | counter | `core`, `state`
|
||||
`windows_cpu_time_total` | Time that processor spent in different modes (dpc, idle, interrupt, privileged, user) | counter | `core`, `mode`
|
||||
`windows_cpu_interrupts_total` | Total number of received and serviced hardware interrupts | counter | `core`
|
||||
`windows_cpu_dpcs_total` | Total number of received and serviced deferred procedure calls (DPCs) | counter | `core`
|
||||
|
||||
These metrics are only exposed on Windows Server 2008R2 and later:
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_cpu_clock_interrupts_total` | Total number of received and serviced clock tick interrupts | counter | `core`
|
||||
`windows_cpu_idle_break_events_total` | Total number of time processor was woken from idle | counter | `core`
|
||||
`windows_cpu_parking_status` | Parking Status represents whether a processor is parked or not | gauge | `core`
|
||||
`windows_cpu_core_frequency_mhz` | Core frequency in megahertz | gauge | `core`
|
||||
`windows_cpu_processor_performance_total` | Processor Performance is the number of CPU cycles executing instructions by each core; it is believed to be similar to the value that the APERF MSR would show, were it exposed | counter | `core`
|
||||
`windows_cpu_processor_mperf_total` | Processor MPerf Total is proportioanl to the number of TSC ticks each core has accumulated while executing instructions. Due to the manner in which it is presented, it should be scaled by 1e2 to properly line up with Processor Performance Total. As above, it is believed to be closely related to the MPERF MSR. | counter | `core`
|
||||
`windows_cpu_processor_rtc_total` | RTC total is assumed to represent the 64Hz tick rate in Windows. It is not by itself useful, but can be used with `windows_cpu_processor_utility_total` to more accurately measure CPU utilisation than with `windows_cpu_time_total` | counter | `core`
|
||||
`windows_cpu_processor_utility_total` | Processor Utility Total is a newer, more accurate measure of CPU utilization, in particular handling modern CPUs with variant CPU frequencies. The rate of this counter divided by the rate of `windows_cpu_processor_rtc_total` should provide an accurate view of CPU utilisation on modern systems, as observed in Task Manager. | counter | `core`
|
||||
`windows_cpu_processor_privileged_utility_total` | Processor Privileged Utility Total, when used in a similar fashion to `windows_cpu_processor_utility_total` will show the portion of CPU utilization which is happening in privileged mode. | counter | `core`
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------|
|
||||
| `windows_cpu_logical_processor` | Number of installed logical processors | counter | `core`, `state` |
|
||||
| `windows_cpu_cstate_seconds_total` | Time spent in low-power idle states | counter | `core`, `state` |
|
||||
| `windows_cpu_time_total` | Time that processor spent in different modes (dpc, idle, interrupt, privileged, user) | counter | `core`, `mode` |
|
||||
| `windows_cpu_interrupts_total` | Total number of received and serviced hardware interrupts | counter | `core` |
|
||||
| `windows_cpu_dpcs_total` | Total number of received and serviced deferred procedure calls (DPCs) | counter | `core` |
|
||||
| `windows_cpu_clock_interrupts_total` | Total number of received and serviced clock tick interrupts | counter | `core` |
|
||||
| `windows_cpu_idle_break_events_total` | Total number of time processor was woken from idle | counter | `core` |
|
||||
| `windows_cpu_parking_status` | Parking Status represents whether a processor is parked or not | gauge | `core` |
|
||||
| `windows_cpu_core_frequency_mhz` | Core frequency in megahertz | gauge | `core` |
|
||||
| `windows_cpu_processor_performance_total` | Processor Performance is the number of CPU cycles executing instructions by each core; it is believed to be similar to the value that the APERF MSR would show, were it exposed | counter | `core` |
|
||||
| `windows_cpu_processor_mperf_total` | Processor MPerf Total is proportioanl to the number of TSC ticks each core has accumulated while executing instructions. Due to the manner in which it is presented, it should be scaled by 1e2 to properly line up with Processor Performance Total. As above, it is believed to be closely related to the MPERF MSR. | counter | `core` |
|
||||
| `windows_cpu_processor_rtc_total` | RTC total is assumed to represent the 64Hz tick rate in Windows. It is not by itself useful, but can be used with `windows_cpu_processor_utility_total` to more accurately measure CPU utilisation than with `windows_cpu_time_total` | counter | `core` |
|
||||
| `windows_cpu_processor_utility_total` | Processor Utility Total is a newer, more accurate measure of CPU utilization, in particular handling modern CPUs with variant CPU frequencies. The rate of this counter divided by the rate of `windows_cpu_processor_rtc_total` should provide an accurate view of CPU utilisation on modern systems, as observed in Task Manager. | counter | `core` |
|
||||
| `windows_cpu_processor_privileged_utility_total` | Processor Privileged Utility Total, when used in a similar fashion to `windows_cpu_processor_utility_total` will show the portion of CPU utilization which is happening in privileged mode. | counter | `core` |
|
||||
|
||||
### Example metric
|
||||
Show frequency of host CPU cores
|
||||
|
||||
@@ -15,13 +15,39 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_cpu_info` | Labelled CPU information | gauge | `architecture`, `device_id`, `description`, `family`, `l2_cache_size` `l3_cache_size`, `name`
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------------------|--------------------------------------|-------|--------------------------------------------------------------|
|
||||
| `windows_cpu_info` | Labelled CPU information | gauge | `architecture`, `description`, `device_id`, `family`, `name` |
|
||||
| `windows_cpu_info_core` | Number of cores per CPU | gauge | `device_id` |
|
||||
| `windows_cpu_info_enabled_core` | Number of enabled cores per CPU | gauge | `device_id` |
|
||||
| `windows_cpu_info_l2_cache_size` | Size of L2 cache per CPU | gauge | `device_id` |
|
||||
| `windows_cpu_info_l3_cache_size` | Size of L3 cache per CPU | gauge | `device_id` |
|
||||
| `windows_cpu_info_logical_processor` | Number of logical processors per CPU | gauge | `device_id` |
|
||||
| `windows_cpu_info_thread` | Number of threads per CPU | gauge | `device_id` |
|
||||
|
||||
### Example metric
|
||||
```
|
||||
windows_cpu_info{architecture="9",description="AMD64 Family 23 Model 49 Stepping 0",device_id="CPU0",family="107",l2_cache_size="32768",l3_cache_size="262144",name="AMD EPYC 7702P 64-Core Processor"} 1
|
||||
# HELP windows_cpu_info Labelled CPU information as provided by Win32_Processor
|
||||
# TYPE windows_cpu_info gauge
|
||||
windows_cpu_info{architecture="9",description="AMD64 Family 25 Model 33 Stepping 2",device_id="CPU0",family="107",name="AMD Ryzen 9 5900X 12-Core Processor"} 1
|
||||
# HELP windows_cpu_info_core Number of cores per CPU
|
||||
# TYPE windows_cpu_info_core gauge
|
||||
windows_cpu_info_core{device_id="CPU0"} 12
|
||||
# HELP windows_cpu_info_enabled_core Number of enabled cores per CPU
|
||||
# TYPE windows_cpu_info_enabled_core gauge
|
||||
windows_cpu_info_enabled_core{device_id="CPU0"} 12
|
||||
# HELP windows_cpu_info_l2_cache_size Size of L2 cache per CPU
|
||||
# TYPE windows_cpu_info_l2_cache_size gauge
|
||||
windows_cpu_info_l2_cache_size{device_id="CPU0"} 6144
|
||||
# HELP windows_cpu_info_l3_cache_size Size of L3 cache per CPU
|
||||
# TYPE windows_cpu_info_l3_cache_size gauge
|
||||
windows_cpu_info_l3_cache_size{device_id="CPU0"} 65536
|
||||
# HELP windows_cpu_info_logical_processor Number of logical processors per CPU
|
||||
# TYPE windows_cpu_info_logical_processor gauge
|
||||
windows_cpu_info_logical_processor{device_id="CPU0"} 24
|
||||
# HELP windows_cpu_info_thread Number of threads per CPU
|
||||
# TYPE windows_cpu_info_thread gauge
|
||||
windows_cpu_info_thread{device_id="CPU0"} 24
|
||||
```
|
||||
The value of the metric is irrelevant, but the labels expose some useful information on the CPU installed in each socket.
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# cs collector
|
||||
|
||||
> [!CAUTION]
|
||||
> This collector is deprecated and will be removed in a future release.
|
||||
> See https://github.com/prometheus-community/windows_exporter/pull/1596 for more information.
|
||||
|
||||
The cs collector exposes metrics detailing the hardware of the computer system
|
||||
|
||||
|||
|
||||
|
||||
36
docs/collector.filetime.md
Normal file
36
docs/collector.filetime.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# filetime collector
|
||||
|
||||
The filetime collector exposes modified timestamps of files in the filesystem.
|
||||
|
||||
The collector
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `filetime`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collectors.filetime.file-patterns`
|
||||
Comma-separated list of file patterns. Each pattern is a glob pattern that can contain `*`, `?`, and `**` (recursive).
|
||||
See https://github.com/bmatcuk/doublestar#patterns for an extended description of the pattern syntax.
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_filetime_mtime_timestamp_seconds` | File modification time | gauge | `file`
|
||||
|
||||
### Example metric
|
||||
|
||||
```
|
||||
# HELP windows_filetime_mtime_timestamp_seconds File modification time
|
||||
# TYPE windows_filetime_mtime_timestamp_seconds gauge
|
||||
windows_filetime_mtime_timestamp_seconds{file="C:\\Users\\admin\\Desktop\\Dashboard.lnk"} 1.726434517e+09
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -2,13 +2,11 @@
|
||||
|
||||
The logon collector exposes metrics detailing the active user logon sessions.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `logon`
|
||||
Classes | [`Win32_LogonSession`](https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-logonsession)
|
||||
Enabled by default? | No
|
||||
|
||||
> :warning: **On some deployments, this collector seems to have some memory/timeout issues**: See [#583](https://github.com/prometheus-community/windows_exporter/issues/583)
|
||||
| | |
|
||||
|---------------------|-----------|
|
||||
| Metric name prefix | `logon` |
|
||||
| Source | Win32 API |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
@@ -16,21 +14,65 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_logon_logon_type` | Number of active user logon sessions | gauge | status
|
||||
| Name | Description | Type | Labels |
|
||||
|-------------------------------------------|--------------------------------------------|-------|------------------------------------|
|
||||
| `windows_logon_session_logon_timestamp_seconds` | timestamp of the logon session in seconds. | gauge | `domain`, `id`, `type`, `username` |
|
||||
|
||||
### Example metric
|
||||
Query the total number of interactive logon sessions
|
||||
```
|
||||
windows_logon_logon_type{status="interactive"}
|
||||
# HELP windows_logon_session_logon_timestamp_seconds timestamp of the logon session in seconds.
|
||||
# TYPE windows_logon_session_logon_timestamp_seconds gauge
|
||||
windows_logon_session_logon_timestamp_seconds{domain="",id="0x0:0x8c54",type="System",username=""} 1.72876928e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x991a",type="Interactive",username="UMFD-1"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x9933",type="Interactive",username="UMFD-0"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x994a",type="Interactive",username="UMFD-0"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x999d",type="Interactive",username="UMFD-1"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0xbf25a",type="Interactive",username="UMFD-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0xbf290",type="Interactive",username="UMFD-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x130241",type="Network",username="vm-jok-dev$"} 1.728769625e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x24f7c9",type="Network",username="vm-jok-dev$"} 1.728770121e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x276846",type="Network",username="vm-jok-dev$"} 1.728770195e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x3e4",type="Service",username="vm-jok-dev$"} 1.728769283e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x3e7",type="System",username="vm-jok-dev$"} 1.728769279e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x71d0f",type="Network",username="vm-jok-dev$"} 1.728769324e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x720a3",type="Network",username="vm-jok-dev$"} 1.728769324e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x725cb",type="Network",username="vm-jok-dev$"} 1.728769324e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x753d8",type="Network",username="vm-jok-dev$"} 1.728769325e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xa3913",type="Network",username="vm-jok-dev$"} 1.728769385e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xbe7f2",type="Network",username="jok"} 1.728769531e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xc76c4",type="RemoteInteractive",username="jok"} 1.728769533e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT AUTHORITY",id="0x0:0x3e3",type="Service",username="IUSR"} 1.728769295e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT AUTHORITY",id="0x0:0x3e5",type="Service",username="LOCAL SERVICE"} 1.728769283e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT Service",id="0x0:0xae4c7",type="Service",username="MSSQLSERVER"} 1.728769425e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT Service",id="0x0:0xb42f1",type="Service",username="SQLTELEMETRY"} 1.728769431e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xbfbac",type="Interactive",username="DWM-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xbfc72",type="Interactive",username="DWM-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xdedd",type="Interactive",username="DWM-1"} 1.728769283e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xdefd",type="Interactive",username="DWM-1"} 1.728769283e+09
|
||||
```
|
||||
|
||||
### Possible values for `type`
|
||||
|
||||
- System
|
||||
- Interactive
|
||||
- Network
|
||||
- Batch
|
||||
- Service
|
||||
- Proxy
|
||||
- Unlock
|
||||
- NetworkCleartext
|
||||
- NewCredentials
|
||||
- RemoteInteractive
|
||||
- CachedInteractive
|
||||
- CachedRemoteInteractive
|
||||
- CachedUnlock
|
||||
|
||||
## Useful queries
|
||||
Query the total number of local and remote (I.E. Terminal Services) interactive sessions.
|
||||
```
|
||||
windows_logon_logon_type{status=~"interactive|remote_interactive"}
|
||||
count(windows_logon_logon_type{type=~"Interactive|RemoteInteractive"}) by (type)
|
||||
```
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
_This collector doesn’t yet have alerting examples, we would appreciate your help adding them!_
|
||||
|
||||
@@ -5,9 +5,9 @@ The memory collector exposes metrics about system memory usage
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `memory`
|
||||
Data source | Perflib
|
||||
Classes | `Win32_PerfRawData_PerfOS_Memory`
|
||||
Enabled by default? | No
|
||||
Data source | Performance Counters
|
||||
Classes | -
|
||||
Enabled by default? | Yes
|
||||
|
||||
## Flags
|
||||
|
||||
@@ -15,46 +15,73 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_memory_available_bytes` | The amount of physical memory immediately available for allocation to a process or for system use. It is equal to the sum of memory assigned to the standby (cached), free and zero page lists | gauge | None
|
||||
`windows_memory_cache_bytes` | Number of bytes currently being used by the file system cache | gauge | None
|
||||
`windows_memory_cache_bytes_peak` | Maximum number of CacheBytes after the system was last restarted | gauge | None
|
||||
`windows_memory_cache_faults_total` | Number of faults which occur when a page sought in the file system cache is not found there and must be retrieved from elsewhere in memory (soft fault) or from disk (hard fault) | counter | None
|
||||
`windows_memory_commit_limit` | Amount of virtual memory, in bytes, that can be committed without having to extend the paging file(s) | gauge | None
|
||||
`windows_memory_committed_bytes` | Amount of committed virtual memory, in bytes | gauge | None
|
||||
`windows_memory_demand_zero_faults_total` | The number of zeroed pages required to satisfy faults. Zeroed pages, pages emptied of previously stored data and filled with zeros, are a security feature of Windows that prevent processes from seeing data stored by earlier processes that used the memory space | counter | None
|
||||
`windows_memory_free_and_zero_page_list_bytes` | The amount of physical memory, in bytes, that is assigned to the free and zero page lists. This memory does not contain cached data. It is immediately available for allocation to a process or for system use | gauge | None
|
||||
`windows_memory_free_system_page_table_entries` | Number of page table entries not being used by the system | gauge | None
|
||||
`windows_memory_modified_page_list_bytes` | The amount of physical memory, in bytes, that is assigned to the modified page list. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. This memory needs to be written out before it will be available for allocation to a process or for system use | gauge | None
|
||||
`windows_memory_page_faults_total` | Overall rate at which faulted pages are handled by the processor | counter | None
|
||||
`windows_memory_swap_page_reads_total` | Number of disk page reads (a single read operation reading several pages is still only counted once) | counter | None
|
||||
`windows_memory_swap_pages_read_total` | Number of pages read across all page reads (ie counting all pages read even if they are read in a single operation) | counter | None
|
||||
`windows_memory_swap_pages_written_total` | Number of pages written across all page writes (ie counting all pages written even if they are written in a single operation) | counter | None
|
||||
`windows_memory_swap_page_operations_total` | Total number of swap page read and writes (PagesPersec) | counter | None
|
||||
`windows_memory_swap_page_writes_total` | Number of disk page writes (a single write operation writing several pages is still only counted once) | counter | None
|
||||
`windows_memory_pool_nonpaged_allocs_total` | The number of calls to allocate space in the nonpaged pool. The nonpaged pool is an area of system memory area for objects that cannot be written to disk, and must remain in physical memory as long as they are allocated | counter | None
|
||||
`windows_memory_pool_nonpaged_bytes` | Number of bytes in the non-paged pool, an area of the system virtual memory that is used for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated | gauge | None
|
||||
`windows_memory_pool_paged_allocs_total` | Number of calls to allocate space in the paged pool, regardless of the amount of space allocated in each call | counter | None
|
||||
`windows_memory_pool_paged_bytes` | Number of bytes in the paged pool | gauge | None
|
||||
`windows_memory_pool_paged_resident_bytes` | The size, in bytes, of the portion of the paged pool that is currently resident and active in physical memory. The paged pool is an area of the system virtual memory that is used for objects that can be written to disk when they are not being used | gauge | None
|
||||
`windows_memory_standby_cache_core_bytes` | The amount of physical memory, in bytes, that is assigned to the core standby cache page lists. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. It is immediately available for allocation to a process or for system use. If the system runs out of available free and zero memory, memory on lower priority standby cache page lists will be repurposed before memory on higher priority standby cache page lists | gauge | None
|
||||
`windows_memory_standby_cache_normal_priority_bytes` | The amount of physical memory, in bytes, that is assigned to the normal priority standby cache page lists. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. It is immediately available for allocation to a process or for system use. If the system runs out of available free and zero memory, memory on lower priority standby cache page lists will be repurposed before memory on higher priority standby cache page lists | gauge | None
|
||||
`windows_memory_standby_cache_reserve_bytes` | The amount of physical memory, in bytes, that is assigned to the reserve standby cache page lists. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. It is immediately available for allocation to a process or for system use. If the system runs out of available free and zero memory, memory on lower priority standby cache page lists will be repurposed before memory on higher priority standby cache page lists | gauge | None
|
||||
`windows_memory_system_cache_resident_bytes` | The size, in bytes, of the portion of the system file cache which is currently resident and active in physical memory | gauge | None
|
||||
`windows_memory_system_code_resident_bytes` | The size, in bytes, of the pageable operating system code that is currently resident and active in physical memory. This value is a component of Memory\\System Code Total Bytes. Memory\\System Code Resident Bytes (and Memory\\System Code Total Bytes) does not include code that must remain in physical memory and cannot be written to disk | gauge | None
|
||||
`windows_memory_system_code_total_bytes` | The size, in bytes, of the pageable operating system code currently mapped into the system virtual address space. This value is calculated by summing the bytes in Ntoskrnl.exe, Hal.dll, the boot drivers, and file systems loaded by Ntldr/osloader. This counter does not include code that must remain in physical memory and cannot be written to disk | gauge | None
|
||||
`windows_memory_system_driver_resident_bytes` | The size, in bytes, of the pageable physical memory being used by device drivers. It is the working set (physical memory area) of the drivers. This value is a component of Memory\\System Driver Total Bytes, which also includes driver memory that has been written to disk. Neither Memory\\System Driver Resident Bytes nor Memory\\System Driver Total Bytes includes memory that cannot be written to disk | gauge | None
|
||||
`windows_memory_system_driver_total_bytes` | The size, in bytes, of the pageable virtual memory currently being used by device drivers. Pageable memory can be written to disk when it is not being used. It includes both physical memory (Memory\\System Driver Resident Bytes) and code and data paged to disk. It is a component of Memory\\System Code Total Bytes | gauge | None
|
||||
`windows_memory_transition_faults_total` | Number of faults rate at which page faults are resolved by recovering pages that were being used by another process sharing the page, or were on the modified page list or the standby list, or were being written to disk at the time of the page fault. The pages were recovered without additional disk activity. Transition faults are counted in numbers of faults; because only one page is faulted in each operation, it is also equal to the number of pages faulted | counter | None
|
||||
`windows_memory_transition_pages_repurposed_total` | Transition Pages RePurposed is the rate at which the number of transition cache pages were reused for a different purpose. These pages would have otherwise remained in the page cache to provide a (fast) soft fault (instead of retrieving it from backing store) in the event the page was accessed in the future | counter | None
|
||||
`windows_memory_write_copies_total` | The number of page faults caused by attempting to write that were satisfied by copying the page from elsewhere in physical memory | counter | None
|
||||
| Name | Description | Type | Labels |
|
||||
|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
|
||||
| `windows_memory_available_bytes` | The amount of physical memory immediately available for allocation to a process or for system use. It is equal to the sum of memory assigned to the standby (cached), free and zero page lists | gauge | None |
|
||||
| `windows_memory_cache_bytes` | Number of bytes currently being used by the file system cache | gauge | None |
|
||||
| `windows_memory_cache_bytes_peak` | Maximum number of CacheBytes after the system was last restarted | gauge | None |
|
||||
| `windows_memory_cache_faults_total` | Number of faults which occur when a page sought in the file system cache is not found there and must be retrieved from elsewhere in memory (soft fault) or from disk (hard fault) | counter | None |
|
||||
| `windows_memory_commit_limit` | Amount of virtual memory, in bytes, that can be committed without having to extend the paging file(s) | gauge | None |
|
||||
| `windows_memory_committed_bytes` | Amount of committed virtual memory, in bytes | gauge | None |
|
||||
| `windows_memory_demand_zero_faults_total` | The number of zeroed pages required to satisfy faults. Zeroed pages, pages emptied of previously stored data and filled with zeros, are a security feature of Windows that prevent processes from seeing data stored by earlier processes that used the memory space | counter | None |
|
||||
| `windows_memory_free_and_zero_page_list_bytes` | The amount of physical memory, in bytes, that is assigned to the free and zero page lists. This memory does not contain cached data. It is immediately available for allocation to a process or for system use | gauge | None |
|
||||
| `windows_memory_free_system_page_table_entries` | Number of page table entries not being used by the system | gauge | None |
|
||||
| `windows_memory_modified_page_list_bytes` | The amount of physical memory, in bytes, that is assigned to the modified page list. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. This memory needs to be written out before it will be available for allocation to a process or for system use | gauge | None |
|
||||
| `windows_memory_page_faults_total` | Overall rate at which faulted pages are handled by the processor | counter | None |
|
||||
| `windows_memory_swap_page_reads_total` | Number of disk page reads (a single read operation reading several pages is still only counted once) | counter | None |
|
||||
| `windows_memory_swap_pages_read_total` | Number of pages read across all page reads (ie counting all pages read even if they are read in a single operation) | counter | None |
|
||||
| `windows_memory_swap_pages_written_total` | Number of pages written across all page writes (ie counting all pages written even if they are written in a single operation) | counter | None |
|
||||
| `windows_memory_swap_page_operations_total` | Total number of swap page read and writes (PagesPersec) | counter | None |
|
||||
| `windows_memory_swap_page_writes_total` | Number of disk page writes (a single write operation writing several pages is still only counted once) | counter | None |
|
||||
| `windows_memory_physical_free_bytes` | Bytes of physical memory currently unused and available | gauge | None |
|
||||
| `windows_memory_physical_total_bytes` | Total bytes of physical memory available to the operating system. This value does not necessarily indicate the true amount of physical memory, but what is reported to the operating system as available to it | gauge | None |
|
||||
| `windows_memory_pool_nonpaged_allocs_total` | The number of calls to allocate space in the nonpaged pool. The nonpaged pool is an area of system memory area for objects that cannot be written to disk, and must remain in physical memory as long as they are allocated | counter | None |
|
||||
| `windows_memory_pool_nonpaged_bytes` | Number of bytes in the non-paged pool, an area of the system virtual memory that is used for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated | gauge | None |
|
||||
| `windows_memory_pool_paged_allocs_total` | Number of calls to allocate space in the paged pool, regardless of the amount of space allocated in each call | counter | None |
|
||||
| `windows_memory_pool_paged_bytes` | Number of bytes in the paged pool | gauge | None |
|
||||
| `windows_memory_pool_paged_resident_bytes` | The size, in bytes, of the portion of the paged pool that is currently resident and active in physical memory. The paged pool is an area of the system virtual memory that is used for objects that can be written to disk when they are not being used | gauge | None |
|
||||
| `windows_memory_process_memory_limit_bytes` | Maximum number of bytes of memory that can be allocated to a process | gauge | None |
|
||||
| `windows_memory_standby_cache_core_bytes` | The amount of physical memory, in bytes, that is assigned to the core standby cache page lists. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. It is immediately available for allocation to a process or for system use. If the system runs out of available free and zero memory, memory on lower priority standby cache page lists will be repurposed before memory on higher priority standby cache page lists | gauge | None |
|
||||
| `windows_memory_standby_cache_normal_priority_bytes` | The amount of physical memory, in bytes, that is assigned to the normal priority standby cache page lists. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. It is immediately available for allocation to a process or for system use. If the system runs out of available free and zero memory, memory on lower priority standby cache page lists will be repurposed before memory on higher priority standby cache page lists | gauge | None |
|
||||
| `windows_memory_standby_cache_reserve_bytes` | The amount of physical memory, in bytes, that is assigned to the reserve standby cache page lists. This memory contains cached data and code that is not actively in use by processes, the system and the system cache. It is immediately available for allocation to a process or for system use. If the system runs out of available free and zero memory, memory on lower priority standby cache page lists will be repurposed before memory on higher priority standby cache page lists | gauge | None |
|
||||
| `windows_memory_system_cache_resident_bytes` | The size, in bytes, of the portion of the system file cache which is currently resident and active in physical memory | gauge | None |
|
||||
| `windows_memory_system_code_resident_bytes` | The size, in bytes, of the pageable operating system code that is currently resident and active in physical memory. This value is a component of Memory\\System Code Total Bytes. Memory\\System Code Resident Bytes (and Memory\\System Code Total Bytes) does not include code that must remain in physical memory and cannot be written to disk | gauge | None |
|
||||
| `windows_memory_system_code_total_bytes` | The size, in bytes, of the pageable operating system code currently mapped into the system virtual address space. This value is calculated by summing the bytes in Ntoskrnl.exe, Hal.dll, the boot drivers, and file systems loaded by Ntldr/osloader. This counter does not include code that must remain in physical memory and cannot be written to disk | gauge | None |
|
||||
| `windows_memory_system_driver_resident_bytes` | The size, in bytes, of the pageable physical memory being used by device drivers. It is the working set (physical memory area) of the drivers. This value is a component of Memory\\System Driver Total Bytes, which also includes driver memory that has been written to disk. Neither Memory\\System Driver Resident Bytes nor Memory\\System Driver Total Bytes includes memory that cannot be written to disk | gauge | None |
|
||||
| `windows_memory_system_driver_total_bytes` | The size, in bytes, of the pageable virtual memory currently being used by device drivers. Pageable memory can be written to disk when it is not being used. It includes both physical memory (Memory\\System Driver Resident Bytes) and code and data paged to disk. It is a component of Memory\\System Code Total Bytes | gauge | None |
|
||||
| `windows_memory_transition_faults_total` | Number of faults rate at which page faults are resolved by recovering pages that were being used by another process sharing the page, or were on the modified page list or the standby list, or were being written to disk at the time of the page fault. The pages were recovered without additional disk activity. Transition faults are counted in numbers of faults; because only one page is faulted in each operation, it is also equal to the number of pages faulted | counter | None |
|
||||
| `windows_memory_transition_pages_repurposed_total` | Transition Pages RePurposed is the rate at which the number of transition cache pages were reused for a different purpose. These pages would have otherwise remained in the page cache to provide a (fast) soft fault (instead of retrieving it from backing store) in the event the page was accessed in the future | counter | None |
|
||||
| `windows_memory_write_copies_total` | The number of page faults caused by attempting to write that were satisfied by copying the page from elsewhere in physical memory | counter | None |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
Show memory usage for instance (%)
|
||||
```
|
||||
100 - 100 * windows_memory_physical_free_bytes{instance="localhost"} / windows_memory_physical_total_bytes
|
||||
```
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
|
||||
**prometheus.rules**
|
||||
```yaml
|
||||
# Alert on hosts that have exhausted all available physical memory
|
||||
- alert: MemoryExhausted
|
||||
expr: windows_os_physical_memory_free_bytes == 0
|
||||
for: 10m
|
||||
labels:
|
||||
severity: high
|
||||
annotations:
|
||||
summary: "Host {{ $labels.instance }} is out of memory"
|
||||
description: "{{ $labels.instance }} has exhausted all available physical memory"
|
||||
|
||||
# Alert on hosts with greater than 90% memory usage
|
||||
- alert: MemoryLow
|
||||
expr: 100 - 100 * windows_memory_physical_free_bytes{instance="localhost"} / windows_memory_physical_total_bytes > 90
|
||||
for: 10m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Memory usage for host {{ $labels.instance }} is greater than 90%"
|
||||
```
|
||||
|
||||
186
docs/collector.mscluster.md
Normal file
186
docs/collector.mscluster.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# mscluster_cluster collector
|
||||
|
||||
The MSCluster_Cluster class is a dynamic WMI class that represents a cluster.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `mscluster`
|
||||
Classes | `MSCluster_Cluster`,`MSCluster_Network`,`MSCluster_Node`,`MSCluster_Resource`,`MSCluster_ResourceGroup`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collectors.mscluster.enabled`
|
||||
Comma-separated list of collectors to use, for example:
|
||||
`--collectors.mscluster.enabled=cluster,network,node,resource,resouregroup`.
|
||||
Matching is case-sensitive.
|
||||
|
||||
## Metrics
|
||||
|
||||
### Cluster
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|--------|
|
||||
| `mscluster_cluster_AddEvictDelay` | Provides access to the cluster's AddEvictDelay property, which is the number a seconds that a new node is delayed after an eviction of another node. | gauge | `name` |
|
||||
| `mscluster_cluster_AdminAccessPoint` | The type of the cluster administrative access point. | gauge | `name` |
|
||||
| `mscluster_cluster_AutoAssignNodeSite` | Determines whether or not the cluster will attempt to automatically assign nodes to sites based on networks and Active Directory Site information. | gauge | `name` |
|
||||
| `mscluster_cluster_AutoBalancerLevel` | Determines the level of aggressiveness of AutoBalancer. | gauge | `name` |
|
||||
| `mscluster_cluster_AutoBalancerMode` | Determines whether or not the auto balancer is enabled. | gauge | `name` |
|
||||
| `mscluster_cluster_BackupInProgress` | Indicates whether a backup is in progress. | gauge | `name` |
|
||||
| `mscluster_cluster_BlockCacheSize` | CSV BlockCache Size in MB. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusSvcHangTimeout` | Controls how long the cluster network driver waits between Failover Cluster Service heartbeats before it determines that the Failover Cluster Service has stopped responding. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusSvcRegroupOpeningTimeout` | Controls how long a node will wait on other nodes in the opening stage before deciding that they failed. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusSvcRegroupPruningTimeout` | Controls how long the membership leader will wait to reach full connectivity between cluster nodes. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusSvcRegroupStageTimeout` | Controls how long a node will wait on other nodes in a membership stage before deciding that they failed. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusSvcRegroupTickInMilliseconds` | Controls how frequently the membership algorithm is sending periodic membership messages. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusterEnforcedAntiAffinity` | Enables or disables hard enforcement of group anti-affinity classes. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusterFunctionalLevel` | The functional level the cluster is currently running in. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusterGroupWaitDelay` | Maximum time in seconds that a group waits for its preferred node to come online during cluster startup before coming online on a different node. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusterLogLevel` | Controls the level of cluster logging. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusterLogSize` | Controls the maximum size of the cluster log files on each of the nodes. | gauge | `name` |
|
||||
| `mscluster_cluster_ClusterUpgradeVersion` | Specifies the upgrade version the cluster is currently running in. | gauge | `name` |
|
||||
| `mscluster_cluster_CrossSiteDelay` | Controls how long the cluster network driver waits in milliseconds between sending Cluster Service heartbeats across sites. | gauge | `name` |
|
||||
| `mscluster_cluster_CrossSiteThreshold` | Controls how many Cluster Service heartbeats can be missed across sites before it determines that Cluster Service has stopped responding. | gauge | `name` |
|
||||
| `mscluster_cluster_CrossSubnetDelay` | Controls how long the cluster network driver waits in milliseconds between sending Cluster Service heartbeats across subnets. | gauge | `name` |
|
||||
| `mscluster_cluster_CrossSubnetThreshold` | Controls how many Cluster Service heartbeats can be missed across subnets before it determines that Cluster Service has stopped responding. | gauge | `name` |
|
||||
| `mscluster_cluster_CsvBalancer` | Whether automatic balancing for CSV is enabled. | gauge | `name` |
|
||||
| `mscluster_cluster_DatabaseReadWriteMode` | Sets the database read and write mode. | gauge | `name` |
|
||||
| `mscluster_cluster_DefaultNetworkRole` | Provides access to the cluster's DefaultNetworkRole property. | gauge | `name` |
|
||||
| `mscluster_cluster_DetectedCloudPlatform` | | gauge | `name` |
|
||||
| `mscluster_cluster_DetectManagedEvents` | | gauge | `name` |
|
||||
| `mscluster_cluster_DetectManagedEventsThreshold` | | gauge | `name` |
|
||||
| `mscluster_cluster_DisableGroupPreferredOwnerRandomization` | | gauge | `name` |
|
||||
| `mscluster_cluster_DrainOnShutdown` | Whether to drain the node when cluster service is being stopped. | gauge | `name` |
|
||||
| `mscluster_cluster_DynamicQuorumEnabled` | Allows cluster service to adjust node weights as needed to increase availability. | gauge | `name` |
|
||||
| `mscluster_cluster_EnableSharedVolumes` | Enables or disables cluster shared volumes on this cluster. | gauge | `name` |
|
||||
| `mscluster_cluster_FixQuorum` | Provides access to the cluster's FixQuorum property, which specifies if the cluster is in a fix quorum state. | gauge | `name` |
|
||||
| `mscluster_cluster_GracePeriodEnabled` | Whether the node grace period feature of this cluster is enabled. | gauge | `name` |
|
||||
| `mscluster_cluster_GracePeriodTimeout` | The grace period timeout in milliseconds. | gauge | `name` |
|
||||
| `mscluster_cluster_GroupDependencyTimeout` | The timeout after which a group will be brought online despite unsatisfied dependencies | gauge | `name` |
|
||||
| `mscluster_cluster_HangRecoveryAction` | Controls the action to take if the user-mode processes have stopped responding. | gauge | `name` |
|
||||
| `mscluster_cluster_IgnorePersistentStateOnStartup` | Provides access to the cluster's IgnorePersistentStateOnStartup property, which specifies whether the cluster will bring online groups that were online when the cluster was shut down. | gauge | `name` |
|
||||
| `mscluster_cluster_LogResourceControls` | Controls the logging of resource controls. | gauge | `name` |
|
||||
| `mscluster_cluster_LowerQuorumPriorityNodeId` | Specifies the Node ID that has a lower priority when voting for quorum is performed. If the quorum vote is split 50/50%, the specified node's vote would be ignored to break the tie. If this is not set then the cluster will pick a node at random to break the tie. | gauge | `name` |
|
||||
| `mscluster_cluster_MaxNumberOfNodes` | Indicates the maximum number of nodes that may participate in the Cluster. | gauge | `name` |
|
||||
| `mscluster_cluster_MessageBufferLength` | The maximum unacknowledged message count for GEM. | gauge | `name` |
|
||||
| `mscluster_cluster_MinimumNeverPreemptPriority` | Groups with this priority or higher cannot be preempted. | gauge | `name` |
|
||||
| `mscluster_cluster_MinimumPreemptorPriority` | Minimum priority a cluster group must have to be able to preempt another group. | gauge | `name` |
|
||||
| `mscluster_cluster_NetftIPSecEnabled` | Whether IPSec is enabled for cluster internal traffic. | gauge | `name` |
|
||||
| `mscluster_cluster_PlacementOptions` | Various option flags to modify default placement behavior. | gauge | `name` |
|
||||
| `mscluster_cluster_PlumbAllCrossSubnetRoutes` | Plumbs all possible cross subnet routes to all nodes. | gauge | `name` |
|
||||
| `mscluster_cluster_PreventQuorum` | Whether the cluster will ignore group persistent state on startup. | gauge | `name` |
|
||||
| `mscluster_cluster_QuarantineDuration` | The quarantine period timeout in milliseconds. | gauge | `name` |
|
||||
| `mscluster_cluster_QuarantineThreshold` | Number of node failures before it will be quarantined. | gauge | `name` |
|
||||
| `mscluster_cluster_QuorumArbitrationTimeMax` | Controls the maximum time necessary to decide the Quorum owner node. | gauge | `name` |
|
||||
| `mscluster_cluster_QuorumArbitrationTimeMin` | Controls the minimum time necessary to decide the Quorum owner node. | gauge | `name` |
|
||||
| `mscluster_cluster_QuorumLogFileSize` | This property is obsolete. | gauge | `name` |
|
||||
| `mscluster_cluster_QuorumTypeValue` | Get the current quorum type value. -1: Unknown; 1: Node; 2: FileShareWitness; 3: Storage; 4: None | gauge | `name` |
|
||||
| `mscluster_cluster_RequestReplyTimeout` | Controls the request reply time-out period. | gauge | `name` |
|
||||
| `mscluster_cluster_ResiliencyDefaultPeriod` | The default resiliency period, in seconds, for the cluster. | gauge | `name` |
|
||||
| `mscluster_cluster_ResiliencyLevel` | The resiliency level for the cluster. | gauge | `name` |
|
||||
| `mscluster_cluster_ResourceDllDeadlockPeriod` | This property is obsolete. | gauge | `name` |
|
||||
| `mscluster_cluster_RootMemoryReserved` | Controls the amount of memory reserved for the parent partition on all cluster nodes. | gauge | `name` |
|
||||
| `mscluster_cluster_RouteHistoryLength` | The history length for routes to help finding network issues. | gauge | `name` |
|
||||
| `mscluster_cluster_S2DBusTypes` | Bus types for storage spaces direct. | gauge | `name` |
|
||||
| `mscluster_cluster_S2DCacheDesiredState` | Desired state of the storage spaces direct cache. | gauge | `name` |
|
||||
| `mscluster_cluster_S2DCacheFlashReservePercent` | Percentage of allocated flash space to utilize when caching. | gauge | `name` |
|
||||
| `mscluster_cluster_S2DCachePageSizeKBytes` | Page size in KB used by S2D cache. | gauge | `name` |
|
||||
| `mscluster_cluster_S2DEnabled` | Whether direct attached storage (DAS) is enabled. | gauge | `name` |
|
||||
| `mscluster_cluster_S2DIOLatencyThreshold` | The I/O latency threshold for storage spaces direct. | gauge | `name` |
|
||||
| `mscluster_cluster_S2DOptimizations` | Optimization flags for storage spaces direct. | gauge | `name` |
|
||||
| `mscluster_cluster_SameSubnetDelay` | Controls how long the cluster network driver waits in milliseconds between sending Cluster Service heartbeats on the same subnet. | gauge | `name` |
|
||||
| `mscluster_cluster_SameSubnetThreshold` | Controls how many Cluster Service heartbeats can be missed on the same subnet before it determines that Cluster Service has stopped responding. | gauge | `name` |
|
||||
| `mscluster_cluster_SecurityLevel` | Controls the level of security that should apply to intracluster messages. 0: Clear Text; 1: Sign; 2: Encrypt | gauge | `name` |
|
||||
| `mscluster_cluster_SecurityLevelForStorage` | | gauge | `name` |
|
||||
| `mscluster_cluster_SharedVolumeVssWriterOperationTimeout` | CSV VSS Writer operation timeout in seconds. | gauge | `name` |
|
||||
| `mscluster_cluster_ShutdownTimeoutInMinutes` | The maximum time in minutes allowed for cluster resources to come offline during cluster service shutdown. | gauge | `name` |
|
||||
| `mscluster_cluster_UseClientAccessNetworksForSharedVolumes` | Whether the use of client access networks for cluster shared volumes feature of this cluster is enabled. 0: Disabled; 1: Enabled; 2: Auto | gauge | `name` |
|
||||
| `mscluster_cluster_WitnessDatabaseWriteTimeout` | Controls the maximum time in seconds that a cluster database write to a witness can take before the write is abandoned. | gauge | `name` |
|
||||
| `mscluster_cluster_WitnessDynamicWeight` | The weight of the configured witness. | gauge | `name` |
|
||||
| `mscluster_cluster_WitnessRestartInterval` | Controls the witness restart interval. | gauge | `name` |
|
||||
|
||||
### Network
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|--------|
|
||||
| `mscluster_network_Characteristics` | Provides the characteristics of the network. The cluster defines characteristics only for resources. For a description of these characteristics, see [CLUSCTL_RESOURCE_GET_CHARACTERISTICS](https://msdn.microsoft.com/library/aa367466). | gauge | `name` |
|
||||
| `mscluster_network_Flags` | Provides access to the flags set for the network. The cluster defines flags only for resources. For a description of these flags, see [CLUSCTL_RESOURCE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-flags). | gauge | `name` |
|
||||
| `mscluster_network_Metric` | The metric of a cluster network (networks with lower values are used first). If this value is set, then the AutoMetric property is set to false. | gauge | `name` |
|
||||
| `mscluster_network_Role` | Provides access to the network's Role property. The Role property describes the role of the network in the cluster. 0: None; 1: Cluster; 2: Client; 3: Both | gauge | `name` |
|
||||
| `mscluster_network_State` | Provides the current state of the network. 1-1: Unknown; 0: Unavailable; 1: Down; 2: Partitioned; 3: Up | gauge | `name` |
|
||||
|
||||
### Network
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|--------|
|
||||
| `mscluster_node_BuildNumber` | Provides access to the node's BuildNumber property. | gauge | `name` |
|
||||
| `mscluster_node_Characteristics` | Provides access to the characteristics set for the node. For a list of possible characteristics, see [CLUSCTL_NODE_GET_CHARACTERISTICS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-node-get-characteristics). | gauge | `name` |
|
||||
| `mscluster_node_DetectedCloudPlatform` | The dynamic vote weight of the node adjusted by dynamic quorum feature. | gauge | `name` |
|
||||
| `mscluster_node_DynamicWeight` | The dynamic vote weight of the node adjusted by dynamic quorum feature. | gauge | `name` |
|
||||
| `mscluster_node_Flags` | Provides access to the flags set for the node. For a list of possible characteristics, see [CLUSCTL_NODE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-node-get-flags). | gauge | `name` |
|
||||
| `mscluster_node_MajorVersion` | Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed. | gauge | `name` |
|
||||
| `mscluster_node_MinorVersion` | Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed. | gauge | `name` |
|
||||
| `mscluster_node_NeedsPreventQuorum` | Whether the cluster service on that node should be started with prevent quorum flag. | gauge | `name` |
|
||||
| `mscluster_node_NodeDrainStatus` | The current node drain status of a node. 0: Not Initiated; 1: In Progress; 2: Completed; 3: Failed | gauge | `name` |
|
||||
| `mscluster_node_NodeHighestVersion` | Provides access to the node's NodeHighestVersion property, which specifies the highest possible version of the cluster service with which the node can join or communicate. | gauge | `name` |
|
||||
| `mscluster_node_NodeLowestVersion` | Provides access to the node's NodeLowestVersion property, which specifies the lowest possible version of the cluster service with which the node can join or communicate. | gauge | `name` |
|
||||
| `mscluster_node_NodeWeight` | The vote weight of the node. | gauge | `name` |
|
||||
| `mscluster_node_State` | Returns the current state of a node. -1: Unknown; 0: Up; 1: Down; 2: Paused; 3: Joining | gauge | `name` |
|
||||
| `mscluster_node_StatusInformation` | The isolation or quarantine status of the node. | gauge | `name` |
|
||||
|
||||
### Resource
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|--------------------------------------------|
|
||||
| `mscluster_resource_Characteristics` | Provides the characteristics of the object. The cluster defines characteristics only for resources. For a description of these characteristics, see [CLUSCTL_RESOURCE_GET_CHARACTERISTICS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-characteristics). | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_DeadlockTimeout` | Indicates the length of time to wait, in milliseconds, before declaring a deadlock in any call into a resource. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_EmbeddedFailureAction` | The time, in milliseconds, that a resource should remain in a failed state before the Cluster service attempts to restart it. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_Flags` | Provides access to the flags set for the object. The cluster defines flags only for resources. For a description of these flags, see [CLUSCTL_RESOURCE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-flags). | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_IsAlivePollInterval` | Provides access to the resource's IsAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it is operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the IsAlivePollInterval property for the resource type associated with the resource. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_LooksAlivePollInterval` | Provides access to the resource's LooksAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it appears operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the LooksAlivePollInterval property for the resource type associated with the resource. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_MonitorProcessId` | Provides the process ID of the resource host service that is currently hosting the resource. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_OwnerNode` | The node hosting the resource. | gauge | `type`, `owner_group`, `node_name`, `name` |
|
||||
| `mscluster_resource_PendingTimeout` | Provides access to the resource's PendingTimeout property. If a resource cannot be brought online or taken offline in the number of milliseconds specified by the PendingTimeout property, the resource is forcibly terminated. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_ResourceClass` | Gets or sets the resource class of a resource. 0: Unknown; 1: Storage; 2: Network; 32768: Unknown | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_RestartAction` | Provides access to the resource's RestartAction property, which is the action to be taken by the Cluster Service if the resource fails. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_RestartDelay` | Indicates the time delay before a failed resource is restarted. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_RestartPeriod` | Provides access to the resource's RestartPeriod property, which is interval of time, in milliseconds, during which a specified number of restart attempts can be made on a nonresponsive resource. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_RestartThreshold` | Provides access to the resource's RestartThreshold property which is the maximum number of restart attempts that can be made on a resource within an interval defined by the RestartPeriod property before the Cluster Service initiates the action specified by the RestartAction property. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_RetryPeriodOnFailure` | Provides access to the resource's RetryPeriodOnFailure property, which is the interval of time (in milliseconds) that a resource should remain in a failed state before the Cluster service attempts to restart it. | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_State` | The current state of the resource. -1: Unknown; 0: Inherited; 1: Initializing; 2: Online; 3: Offline; 4: Failed; 128: Pending; 129: Online Pending; 130: Offline Pending | gauge | `type`, `owner_group`, `name` |
|
||||
| `mscluster_resource_Subclass` | Provides the list of references to nodes that can be the owner of this resource. | gauge | `type`, `owner_group`, `name` |
|
||||
|
||||
## ResourceGroup
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|---------------------|
|
||||
| `mscluster_resourcegroup_AutoFailbackType` | Provides access to the group's AutoFailbackType property. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_Characteristics` | Provides the characteristics of the group. The cluster defines characteristics only for resources. For a description of these characteristics, see [CLUSCTL_RESOURCE_GET_CHARACTERISTICS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-characteristics). | gauge | `name` |
|
||||
| `mscluster_resourcegroup_ColdStartSetting` | Indicates whether a group can start after a cluster cold start. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_DefaultOwner` | Number of the last node the resource group was activated on or explicitly moved to. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_FailbackWindowEnd` | The FailbackWindowEnd property provides the latest time that the group can be moved back to the node identified as its preferred node. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_FailbackWindowStart` | The FailbackWindowStart property provides the earliest time (that is, local time as kept by the cluster) that the group can be moved back to the node identified as its preferred node. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_FailoverPeriod` | The FailoverPeriod property specifies a number of hours during which a maximum number of failover attempts, specified by the FailoverThreshold property, can occur. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_FailoverThreshold` | The FailoverThreshold property specifies the maximum number of failover attempts. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_Flags` | Provides access to the flags set for the group. The cluster defines flags only for resources. For a description of these flags, see [CLUSCTL_RESOURCE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-flags). | gauge | `name` |
|
||||
| `mscluster_resourcegroup_GroupType` | The Type of the resource group. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_OwnerNode` | The node hosting the resource group. | gauge | `node_name`, `name` |
|
||||
| `mscluster_resourcegroup_Priority` | Priority value of the resource group | gauge | `name` |
|
||||
| `mscluster_resourcegroup_ResiliencyPeriod` | The resiliency period for this group, in seconds. | gauge | `name` |
|
||||
| `mscluster_resourcegroup_State` | The current state of the resource group. -1: Unknown; 0: Online; 1: Offline; 2: Failed; 3: Partial Online; 4: Pending | gauge | `name` |
|
||||
| `mscluster_resourcegroup_UpdateDomain` | | gauge | `name` |
|
||||
|
||||
### Example metric
|
||||
Query the state of all cluster resource owned by node1
|
||||
```
|
||||
windows_mscluster_resource_owner_node{node_name="node1"}
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
Counts the number of Network Name cluster resource
|
||||
```
|
||||
count(windows_mscluster_resource_state{type="Network Name"})
|
||||
```
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,104 +0,0 @@
|
||||
# mscluster_cluster collector
|
||||
|
||||
The MSCluster_Cluster class is a dynamic WMI class that represents a cluster.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `mscluster_cluster`
|
||||
Classes | `MSCluster_Cluster`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`AddEvictDelay` | Provides access to the cluster's AddEvictDelay property, which is the number a seconds that a new node is delayed after an eviction of another node. | gauge | `name`
|
||||
`AdminAccessPoint` | The type of the cluster administrative access point. | gauge | `name`
|
||||
`AutoAssignNodeSite` | Determines whether or not the cluster will attempt to automatically assign nodes to sites based on networks and Active Directory Site information. | gauge | `name`
|
||||
`AutoBalancerLevel` | Determines the level of aggressiveness of AutoBalancer. | gauge | `name`
|
||||
`AutoBalancerMode` | Determines whether or not the auto balancer is enabled. | gauge | `name`
|
||||
`BackupInProgress` | Indicates whether a backup is in progress. | gauge | `name`
|
||||
`BlockCacheSize` | CSV BlockCache Size in MB. | gauge | `name`
|
||||
`ClusSvcHangTimeout` | Controls how long the cluster network driver waits between Failover Cluster Service heartbeats before it determines that the Failover Cluster Service has stopped responding. | gauge | `name`
|
||||
`ClusSvcRegroupOpeningTimeout` | Controls how long a node will wait on other nodes in the opening stage before deciding that they failed. | gauge | `name`
|
||||
`ClusSvcRegroupPruningTimeout` | Controls how long the membership leader will wait to reach full connectivity between cluster nodes. | gauge | `name`
|
||||
`ClusSvcRegroupStageTimeout` | Controls how long a node will wait on other nodes in a membership stage before deciding that they failed. | gauge | `name`
|
||||
`ClusSvcRegroupTickInMilliseconds` | Controls how frequently the membership algorithm is sending periodic membership messages. | gauge | `name`
|
||||
`ClusterEnforcedAntiAffinity` | Enables or disables hard enforcement of group anti-affinity classes. | gauge | `name`
|
||||
`ClusterFunctionalLevel` | The functional level the cluster is currently running in. | gauge | `name`
|
||||
`ClusterGroupWaitDelay` | Maximum time in seconds that a group waits for its preferred node to come online during cluster startup before coming online on a different node. | gauge | `name`
|
||||
`ClusterLogLevel` | Controls the level of cluster logging. | gauge | `name`
|
||||
`ClusterLogSize` | Controls the maximum size of the cluster log files on each of the nodes. | gauge | `name`
|
||||
`ClusterUpgradeVersion` | Specifies the upgrade version the cluster is currently running in. | gauge | `name`
|
||||
`CrossSiteDelay` | Controls how long the cluster network driver waits in milliseconds between sending Cluster Service heartbeats across sites. | gauge | `name`
|
||||
`CrossSiteThreshold` | Controls how many Cluster Service heartbeats can be missed across sites before it determines that Cluster Service has stopped responding. | gauge | `name`
|
||||
`CrossSubnetDelay` | Controls how long the cluster network driver waits in milliseconds between sending Cluster Service heartbeats across subnets. | gauge | `name`
|
||||
`CrossSubnetThreshold` | Controls how many Cluster Service heartbeats can be missed across subnets before it determines that Cluster Service has stopped responding. | gauge | `name`
|
||||
`CsvBalancer` | Whether automatic balancing for CSV is enabled. | gauge | `name`
|
||||
`DatabaseReadWriteMode` | Sets the database read and write mode. | gauge | `name`
|
||||
`DefaultNetworkRole` | Provides access to the cluster's DefaultNetworkRole property. | gauge | `name`
|
||||
`DetectedCloudPlatform` | | gauge | `name`
|
||||
`DetectManagedEvents` | | gauge | `name`
|
||||
`DetectManagedEventsThreshold` | | gauge | `name`
|
||||
`DisableGroupPreferredOwnerRandomization` | | gauge | `name`
|
||||
`DrainOnShutdown` | Whether to drain the node when cluster service is being stopped. | gauge | `name`
|
||||
`DynamicQuorumEnabled` | Allows cluster service to adjust node weights as needed to increase availability. | gauge | `name`
|
||||
`EnableSharedVolumes` | Enables or disables cluster shared volumes on this cluster. | gauge | `name`
|
||||
`FixQuorum` | Provides access to the cluster's FixQuorum property, which specifies if the cluster is in a fix quorum state. | gauge | `name`
|
||||
`GracePeriodEnabled` | Whether the node grace period feature of this cluster is enabled. | gauge | `name`
|
||||
`GracePeriodTimeout` | The grace period timeout in milliseconds. | gauge | `name`
|
||||
`GroupDependencyTimeout` | The timeout after which a group will be brought online despite unsatisfied dependencies | gauge | `name`
|
||||
`HangRecoveryAction` | Controls the action to take if the user-mode processes have stopped responding. | gauge | `name`
|
||||
`IgnorePersistentStateOnStartup` | Provides access to the cluster's IgnorePersistentStateOnStartup property, which specifies whether the cluster will bring online groups that were online when the cluster was shut down. | gauge | `name`
|
||||
`LogResourceControls` | Controls the logging of resource controls. | gauge | `name`
|
||||
`LowerQuorumPriorityNodeId` | Specifies the Node ID that has a lower priority when voting for quorum is performed. If the quorum vote is split 50/50%, the specified node's vote would be ignored to break the tie. If this is not set then the cluster will pick a node at random to break the tie. | gauge | `name`
|
||||
`MaxNumberOfNodes` | Indicates the maximum number of nodes that may participate in the Cluster. | gauge | `name`
|
||||
`MessageBufferLength` | The maximum unacknowledged message count for GEM. | gauge | `name`
|
||||
`MinimumNeverPreemptPriority` | Groups with this priority or higher cannot be preempted. | gauge | `name`
|
||||
`MinimumPreemptorPriority` | Minimum priority a cluster group must have to be able to preempt another group. | gauge | `name`
|
||||
`NetftIPSecEnabled` | Whether IPSec is enabled for cluster internal traffic. | gauge | `name`
|
||||
`PlacementOptions` | Various option flags to modify default placement behavior. | gauge | `name`
|
||||
`PlumbAllCrossSubnetRoutes` | Plumbs all possible cross subnet routes to all nodes. | gauge | `name`
|
||||
`PreventQuorum` | Whether the cluster will ignore group persistent state on startup. | gauge | `name`
|
||||
`QuarantineDuration` | The quarantine period timeout in milliseconds. | gauge | `name`
|
||||
`QuarantineThreshold` | Number of node failures before it will be quarantined. | gauge | `name`
|
||||
`QuorumArbitrationTimeMax` | Controls the maximum time necessary to decide the Quorum owner node. | gauge | `name`
|
||||
`QuorumArbitrationTimeMin` | Controls the minimum time necessary to decide the Quorum owner node. | gauge | `name`
|
||||
`QuorumLogFileSize` | This property is obsolete. | gauge | `name`
|
||||
`QuorumTypeValue` | Get the current quorum type value. -1: Unknown; 1: Node; 2: FileShareWitness; 3: Storage; 4: None | gauge | `name`
|
||||
`RequestReplyTimeout` | Controls the request reply time-out period. | gauge | `name`
|
||||
`ResiliencyDefaultPeriod` | The default resiliency period, in seconds, for the cluster. | gauge | `name`
|
||||
`ResiliencyLevel` | The resiliency level for the cluster. | gauge | `name`
|
||||
`ResourceDllDeadlockPeriod` | This property is obsolete. | gauge | `name`
|
||||
`RootMemoryReserved` | Controls the amount of memory reserved for the parent partition on all cluster nodes. | gauge | `name`
|
||||
`RouteHistoryLength` | The history length for routes to help finding network issues. | gauge | `name`
|
||||
`S2DBusTypes` | Bus types for storage spaces direct. | gauge | `name`
|
||||
`S2DCacheDesiredState` | Desired state of the storage spaces direct cache. | gauge | `name`
|
||||
`S2DCacheFlashReservePercent` | Percentage of allocated flash space to utilize when caching. | gauge | `name`
|
||||
`S2DCachePageSizeKBytes` | Page size in KB used by S2D cache. | gauge | `name`
|
||||
`S2DEnabled` | Whether direct attached storage (DAS) is enabled. | gauge | `name`
|
||||
`S2DIOLatencyThreshold` | The I/O latency threshold for storage spaces direct. | gauge | `name`
|
||||
`S2DOptimizations` | Optimization flags for storage spaces direct. | gauge | `name`
|
||||
`SameSubnetDelay` | Controls how long the cluster network driver waits in milliseconds between sending Cluster Service heartbeats on the same subnet. | gauge | `name`
|
||||
`SameSubnetThreshold` | Controls how many Cluster Service heartbeats can be missed on the same subnet before it determines that Cluster Service has stopped responding. | gauge | `name`
|
||||
`SecurityLevel` | Controls the level of security that should apply to intracluster messages. 0: Clear Text; 1: Sign; 2: Encrypt | gauge | `name`
|
||||
`SecurityLevelForStorage` | | gauge | `name`
|
||||
`SharedVolumeVssWriterOperationTimeout` | CSV VSS Writer operation timeout in seconds. | gauge | `name`
|
||||
`ShutdownTimeoutInMinutes` | The maximum time in minutes allowed for cluster resources to come offline during cluster service shutdown. | gauge | `name`
|
||||
`UseClientAccessNetworksForSharedVolumes` | Whether the use of client access networks for cluster shared volumes feature of this cluster is enabled. 0: Disabled; 1: Enabled; 2: Auto | gauge | `name`
|
||||
`WitnessDatabaseWriteTimeout` | Controls the maximum time in seconds that a cluster database write to a witness can take before the write is abandoned. | gauge | `name`
|
||||
`WitnessDynamicWeight` | The weight of the configured witness. | gauge | `name`
|
||||
`WitnessRestartInterval` | Controls the witness restart interval. | gauge | `name`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,32 +0,0 @@
|
||||
# mscluster_network collector
|
||||
|
||||
The MSCluster_Network class is a dynamic WMI class that represents cluster networks.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `mscluster_network`
|
||||
Classes | `MSCluster_Network`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`Characteristics` | Provides the characteristics of the network. The cluster defines characteristics only for resources. For a description of these characteristics, see [CLUSCTL_RESOURCE_GET_CHARACTERISTICS](https://msdn.microsoft.com/library/aa367466). | gauge | `name`
|
||||
`Flags` | Provides access to the flags set for the network. The cluster defines flags only for resources. For a description of these flags, see [CLUSCTL_RESOURCE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-flags). | gauge | `name`
|
||||
`Metric` | The metric of a cluster network (networks with lower values are used first). If this value is set, then the AutoMetric property is set to false. | gauge | `name`
|
||||
`Role` | Provides access to the network's Role property. The Role property describes the role of the network in the cluster. 0: None; 1: Cluster; 2: Client; 3: Both | gauge | `name`
|
||||
`State` | Provides the current state of the network. 1-1: Unknown; 0: Unavailable; 1: Down; 2: Partitioned; 3: Up | gauge | `name`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,41 +0,0 @@
|
||||
# mscluster_node collector
|
||||
|
||||
The MSCluster_Node class is a dynamic WMI class that represents a cluster node.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `mscluster_node`
|
||||
Classes | `MSCluster_Node`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`BuildNumber` | Provides access to the node's BuildNumber property. | gauge | `name`
|
||||
`Characteristics` | Provides access to the characteristics set for the node. For a list of possible characteristics, see [CLUSCTL_NODE_GET_CHARACTERISTICS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-node-get-characteristics). | gauge | `name`
|
||||
`DetectedCloudPlatform` | The dynamic vote weight of the node adjusted by dynamic quorum feature. | gauge | `name`
|
||||
`DynamicWeight` | The dynamic vote weight of the node adjusted by dynamic quorum feature. | gauge | `name`
|
||||
`Flags` | Provides access to the flags set for the node. For a list of possible characteristics, see [CLUSCTL_NODE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-node-get-flags). | gauge | `name`
|
||||
`MajorVersion` | Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed. | gauge | `name`
|
||||
`MinorVersion` | Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed. | gauge | `name`
|
||||
`NeedsPreventQuorum` | Whether the cluster service on that node should be started with prevent quorum flag. | gauge | `name`
|
||||
`NodeDrainStatus` | The current node drain status of a node. 0: Not Initiated; 1: In Progress; 2: Completed; 3: Failed | gauge | `name`
|
||||
`NodeHighestVersion` | Provides access to the node's NodeHighestVersion property, which specifies the highest possible version of the cluster service with which the node can join or communicate. | gauge | `name`
|
||||
`NodeLowestVersion` | Provides access to the node's NodeLowestVersion property, which specifies the lowest possible version of the cluster service with which the node can join or communicate. | gauge | `name`
|
||||
`NodeWeight` | The vote weight of the node. | gauge | `name`
|
||||
`State` | Returns the current state of a node. -1: Unknown; 0: Up; 1: Down; 2: Paused; 3: Joining | gauge | `name`
|
||||
`StatusInformation` | The isolation or quarantine status of the node. | gauge | `name`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,50 +0,0 @@
|
||||
# mscluster_resource collector
|
||||
|
||||
The MSCluster_resource class is a dynamic WMI class that represents a cluster resource.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `mscluster_resource`
|
||||
Classes | `MSCluster_Resource`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`Characteristics` | Provides the characteristics of the object. The cluster defines characteristics only for resources. For a description of these characteristics, see [CLUSCTL_RESOURCE_GET_CHARACTERISTICS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-characteristics). | gauge | `type`, `owner_group`, `name`
|
||||
`DeadlockTimeout` | Indicates the length of time to wait, in milliseconds, before declaring a deadlock in any call into a resource. | gauge | `type`, `owner_group`, `name`
|
||||
`EmbeddedFailureAction` | The time, in milliseconds, that a resource should remain in a failed state before the Cluster service attempts to restart it. | gauge | `type`, `owner_group`, `name`
|
||||
`Flags` | Provides access to the flags set for the object. The cluster defines flags only for resources. For a description of these flags, see [CLUSCTL_RESOURCE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-flags). | gauge | `type`, `owner_group`, `name`
|
||||
`IsAlivePollInterval` | Provides access to the resource's IsAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it is operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the IsAlivePollInterval property for the resource type associated with the resource. | gauge | `type`, `owner_group`, `name`
|
||||
`LooksAlivePollInterval` | Provides access to the resource's LooksAlivePollInterval property, which is the recommended interval in milliseconds at which the Cluster Service should poll the resource to determine whether it appears operational. If the property is set to 0xFFFFFFFF, the Cluster Service uses the LooksAlivePollInterval property for the resource type associated with the resource. | gauge | `type`, `owner_group`, `name`
|
||||
`MonitorProcessId` | Provides the process ID of the resource host service that is currently hosting the resource. | gauge | `type`, `owner_group`, `name`
|
||||
`OwnerNode` | The node hosting the resource. | gauge | `type`, `owner_group`, `node_name`, `name`
|
||||
`PendingTimeout` | Provides access to the resource's PendingTimeout property. If a resource cannot be brought online or taken offline in the number of milliseconds specified by the PendingTimeout property, the resource is forcibly terminated. | gauge | `type`, `owner_group`, `name`
|
||||
`ResourceClass` | Gets or sets the resource class of a resource. 0: Unknown; 1: Storage; 2: Network; 32768: Unknown | gauge | `type`, `owner_group`, `name`
|
||||
`RestartAction` | Provides access to the resource's RestartAction property, which is the action to be taken by the Cluster Service if the resource fails. | gauge | `type`, `owner_group`, `name`
|
||||
`RestartDelay` | Indicates the time delay before a failed resource is restarted. | gauge | `type`, `owner_group`, `name`
|
||||
`RestartPeriod` | Provides access to the resource's RestartPeriod property, which is interval of time, in milliseconds, during which a specified number of restart attempts can be made on a nonresponsive resource. | gauge | `type`, `owner_group`, `name`
|
||||
`RestartThreshold` | Provides access to the resource's RestartThreshold property which is the maximum number of restart attempts that can be made on a resource within an interval defined by the RestartPeriod property before the Cluster Service initiates the action specified by the RestartAction property. | gauge | `type`, `owner_group`, `name`
|
||||
`RetryPeriodOnFailure` | Provides access to the resource's RetryPeriodOnFailure property, which is the interval of time (in milliseconds) that a resource should remain in a failed state before the Cluster service attempts to restart it. | gauge | `type`, `owner_group`, `name`
|
||||
`State` | The current state of the resource. -1: Unknown; 0: Inherited; 1: Initializing; 2: Online; 3: Offline; 4: Failed; 128: Pending; 129: Online Pending; 130: Offline Pending | gauge | `type`, `owner_group`, `name`
|
||||
`Subclass` | Provides the list of references to nodes that can be the owner of this resource. | gauge | `type`, `owner_group`, `name`
|
||||
|
||||
### Example metric
|
||||
Query the state of all cluster resource owned by node1
|
||||
```
|
||||
windows_mscluster_resource_owner_node{node_name="node1"}
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
Counts the number of Network Name cluster resource
|
||||
```
|
||||
count(windows_mscluster_resource_state{type="Network Name"})
|
||||
```
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,48 +0,0 @@
|
||||
# mscluster_resourcegroup collector
|
||||
|
||||
The MSCluster_ResourceGroup class is a dynamic WMI class that represents a cluster group.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `mscluster_resourcegroup`
|
||||
Classes | `MSCluster_ResourceGroup`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`AutoFailbackType` | Provides access to the group's AutoFailbackType property. | gauge | `name`
|
||||
`Characteristics` | Provides the characteristics of the group. The cluster defines characteristics only for resources. For a description of these characteristics, see [CLUSCTL_RESOURCE_GET_CHARACTERISTICS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-characteristics). | gauge | `name`
|
||||
`ColdStartSetting` | Indicates whether a group can start after a cluster cold start. | gauge | `name`
|
||||
`DefaultOwner` | Number of the last node the resource group was activated on or explicitly moved to. | gauge | `name`
|
||||
`FailbackWindowEnd` | The FailbackWindowEnd property provides the latest time that the group can be moved back to the node identified as its preferred node. | gauge | `name`
|
||||
`FailbackWindowStart` | The FailbackWindowStart property provides the earliest time (that is, local time as kept by the cluster) that the group can be moved back to the node identified as its preferred node. | gauge | `name`
|
||||
`FailoverPeriod` | The FailoverPeriod property specifies a number of hours during which a maximum number of failover attempts, specified by the FailoverThreshold property, can occur. | gauge | `name`
|
||||
`FailoverThreshold` | The FailoverThreshold property specifies the maximum number of failover attempts. | gauge | `name`
|
||||
`Flags` | Provides access to the flags set for the group. The cluster defines flags only for resources. For a description of these flags, see [CLUSCTL_RESOURCE_GET_FLAGS](https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mscs/clusctl-resource-get-flags). | gauge | `name`
|
||||
`GroupType` | The Type of the resource group. | gauge | `name`
|
||||
`OwnerNode` | The node hosting the resource group. | gauge | `node_name`, `name`
|
||||
`Priority` | Priority value of the resource group | gauge | `name`
|
||||
`ResiliencyPeriod` | The resiliency period for this group, in seconds. | gauge | `name`
|
||||
`State` | The current state of the resource group. -1: Unknown; 0: Online; 1: Offline; 2: Failed; 3: Partial Online; 4: Pending | gauge | `name`
|
||||
`UpdateDomain` | | gauge | `name`
|
||||
|
||||
### Example metric
|
||||
Query the state of all cluster group owned by node1
|
||||
```
|
||||
windows_mscluster_resourcegroup_owner_node{node_name="node1"}
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
Counts the number of cluster group by type
|
||||
```
|
||||
count_values("count", windows_mscluster_resourcegroup_group_type)
|
||||
```
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
113
docs/collector.netframework.md
Normal file
113
docs/collector.netframework.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# netframework collector
|
||||
|
||||
The netframework collector exposes metrics about dotnet framework.
|
||||
|
||||
| | |
|
||||
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Metric name prefix** | `netframework_clrexceptions` |
|
||||
| **Classes** | `Win32_PerfRawData_NETFramework_NETCLRExceptions`, `Win32_PerfRawData_NETFramework_NETCLRInterop`, `Win32_PerfRawData_NETFramework_NETCLRJit`, `Win32_PerfRawData_NETFramework_NETCLRLoading`, `Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads`, `Win32_PerfRawData_NETFramework_NETCLRMemory`, `Win32_PerfRawData_NETFramework_NETCLRRemoting`, `Win32_PerfRawData_NETFramework_NETCLRSecurity` |
|
||||
| **Enabled by default?** | No |
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
### CLR Exceptions
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrexceptions_exceptions_thrown_total` | Displays the total number of exceptions thrown since the application started. This includes both .NET exceptions and unmanaged exceptions that are converted into .NET exceptions. | counter | `process` |
|
||||
| `windows_netframework_clrexceptions_exceptions_filters_total` | Displays the total number of .NET exception filters executed. An exception filter evaluates regardless of whether an exception is handled. | counter | `process` |
|
||||
| `windows_netframework_clrexceptions_exceptions_finallys_total` | Displays the total number of finally blocks executed. Only the finally blocks executed for an exception are counted; finally blocks on normal code paths are not counted by this counter. | counter | `process` |
|
||||
| `windows_netframework_clrexceptions_throw_to_catch_depth_total` | Displays the total number of stack frames traversed, from the frame that threw the exception to the frame that handled the exception. | counter | `process` |
|
||||
|
||||
### CLR Interop
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrinterop_com_callable_wrappers_total` | Displays the current number of COM callable wrappers (CCWs). A CCW is a proxy for a managed object being referenced from an unmanaged COM client. | counter | `process` |
|
||||
| `windows_netframework_clrinterop_interop_marshalling_total` | Displays the total number of times arguments and return values have been marshaled from managed to unmanaged code, and vice versa, since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrinterop_interop_stubs_created_total` | Displays the current number of stubs created by the common language runtime. Stubs are responsible for marshaling arguments and return values from managed to unmanaged code, and vice versa, during a COM interop call or a platform invoke call. | counter | `process` |
|
||||
|
||||
### CLR JIT
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrjit_jit_methods_total` | Displays the total number of methods JIT-compiled since the application started. This counter does not include pre-JIT-compiled methods. | counter | `process` |
|
||||
| `windows_netframework_clrjit_jit_time_percent` | Displays the percentage of time spent in JIT compilation. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase occurs when a method and its dependencies are compiled. | gauge | `process` |
|
||||
| `windows_netframework_clrjit_jit_standard_failures_total` | Displays the peak number of methods the JIT compiler has failed to compile since the application started. This failure can occur if the MSIL cannot be verified or if there is an internal error in the JIT compiler. | counter | `process` |
|
||||
| `windows_netframework_clrjit_jit_il_bytes_total` | Displays the total number of Microsoft intermediate language (MSIL) bytes compiled by the just-in-time (JIT) compiler since the application started | counter | `process` |
|
||||
|
||||
### CLR Loading
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrloading_loader_heap_size_bytes` | Displays the current size, in bytes, of the memory committed by the class loader across all application domains. Committed memory is the physical space reserved in the disk paging file. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_appdomains_loaded_current` | Displays the current number of application domains loaded in this application. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_assemblies_loaded_current` | Displays the current number of assemblies loaded across all application domains in the currently running application. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_classes_loaded_current` | Displays the current number of classes loaded in all assemblies. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_appdomains_loaded_total` | Displays the peak number of application domains loaded since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrloading_appdomains_unloaded_total` | Displays the total number of application domains unloaded since the application started. If an application domain is loaded and unloaded multiple times, this counter increments each time the application domain is unloaded. | counter | `process` |
|
||||
| `windows_netframework_clrloading_assemblies_loaded_total` | Displays the total number of assemblies loaded since the application started. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | counter | `process` |
|
||||
| `windows_netframework_clrloading_classes_loaded_total` | Displays the cumulative number of classes loaded in all assemblies since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrloading_class_load_failures_total` | Displays the peak number of classes that have failed to load since the application started. | counter | `process` |
|
||||
|
||||
### CLR Locks and Threads
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrlocksandthreads_current_queue_length` | Displays the total number of threads that are currently waiting to acquire a managed lock in the application. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_current_logical_threads` | Displays the number of current managed thread objects in the application. This counter maintains the count of both running and stopped threads. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_physical_threads_current` | Displays the number of native operating system threads created and owned by the common language runtime to act as underlying threads for managed thread objects. This counter's value does not include the threads used by the runtime in its internal operations; it is a subset of the threads in the operating system process. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_recognized_threads_current` | Displays the number of threads that are currently recognized by the runtime. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_recognized_threads_total` | Displays the total number of threads that have been recognized by the runtime since the application started. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | counter | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_queue_length_total` | Displays the total number of threads that waited to acquire a managed lock since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_contentions_total` | Displays the total number of times that threads in the runtime have attempted to acquire a managed lock unsuccessfully. | counter | `process` |
|
||||
|
||||
### CLR Memory
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrmemory_allocated_bytes_total` | Displays the total number of bytes allocated on the garbage collection heap. | counter | `process` |
|
||||
| `windows_netframework_clrmemory_finalization_survivors` | Displays the number of garbage-collected objects that survive a collection because they are waiting to be finalized. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_heap_size_bytes` | Displays the maximum bytes that can be allocated; it does not indicate the current number of bytes allocated. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_promoted_bytes` | Displays the bytes that were promoted from the generation to the next one during the last GC. Memory is promoted when it survives a garbage collection. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_number_gc_handles` | Displays the current number of garbage collection handles in use. Garbage collection handles are handles to resources external to the common language runtime and the managed environment. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_collections_total` | Displays the number of times the generation objects are garbage collected since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrmemory_induced_gc_total` | Displays the peak number of times garbage collection was performed because of an explicit call to GC.Collect. | counter | `process` |
|
||||
| `windows_netframework_clrmemory_number_pinned_objects` | Displays the number of pinned objects encountered in the last garbage collection. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_number_sink_blocksinuse` | Displays the current number of synchronization blocks in use. Synchronization blocks are per-object data structures allocated for storing synchronization information. They hold weak references to managed objects and must be scanned by the garbage collector. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_committed_bytes` | Displays the amount of virtual memory, in bytes, currently committed by the garbage collector. Committed memory is the physical memory for which space has been reserved in the disk paging file. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_reserved_bytes` | Displays the amount of virtual memory, in bytes, currently reserved by the garbage collector. Reserved memory is the virtual memory space reserved for the application when no disk or main memory pages have been used. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_gc_time_percent` | Displays the percentage of time that was spent performing a garbage collection in the last sample. | gauge | `process` |
|
||||
|
||||
### CLR Remoting
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrremoting_channels_total` | Displays the total number of remoting channels registered across all application domains since application started. | counter | `process` |
|
||||
| `windows_netframework_clrremoting_context_bound_classes_loaded` | Displays the current number of context-bound classes that are loaded. | gauge | `process` |
|
||||
| `windows_netframework_clrremoting_context_bound_objects_total` | Displays the total number of context-bound objects allocated. | counter | `process` |
|
||||
| `windows_netframework_clrremoting_context_proxies_total` | Displays the total number of remoting proxy objects in this process since it started. | counter | `process` |
|
||||
| `windows_netframework_clrremoting_contexts` | Displays the current number of remoting contexts in the application. | gauge | `process` |
|
||||
| `windows_netframework_clrremoting_remote_calls_total` | Displays the total number of remote procedure calls invoked since the application started. | counter | `process` |
|
||||
|
||||
### CLR Security
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrsecurity_link_time_checks_total` | Displays the total number of link-time code access security checks since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrsecurity_rt_checks_time_percent` | Displays the percentage of time spent performing runtime code access security checks in the last sample. | gauge | `process` |
|
||||
| `windows_netframework_clrsecurity_stack_walk_depth` | Displays the depth of the stack during that last runtime code access security check. | gauge | `process` |
|
||||
| `windows_netframework_clrsecurity_runtime_checks_total` | Displays the total number of runtime code access security checks performed since the application started. | counter | `process` |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,31 +0,0 @@
|
||||
# netframework_clrexceptions collector
|
||||
|
||||
The netframework_clrexceptions collector exposes metrics about CLR exceptions in the dotnet framework.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrexceptions`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRExceptions`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrexceptions_exceptions_thrown_total` | Displays the total number of exceptions thrown since the application started. This includes both .NET exceptions and unmanaged exceptions that are converted into .NET exceptions. | counter | `process`
|
||||
`windows_netframework_clrexceptions_exceptions_filters_total` | Displays the total number of .NET exception filters executed. An exception filter evaluates regardless of whether an exception is handled. | counter | `process`
|
||||
`windows_netframework_clrexceptions_exceptions_finallys_total` | Displays the total number of finally blocks executed. Only the finally blocks executed for an exception are counted; finally blocks on normal code paths are not counted by this counter. | counter | `process`
|
||||
`windows_netframework_clrexceptions_throw_to_catch_depth_total` | Displays the total number of stack frames traversed, from the frame that threw the exception to the frame that handled the exception. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,30 +0,0 @@
|
||||
# netframework_clrinterop collector
|
||||
|
||||
The netframework_clrinterop collector exposes metrics about interop between the dotnet framework and outside components.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrinterop`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRInterop`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrinterop_com_callable_wrappers_total` | Displays the current number of COM callable wrappers (CCWs). A CCW is a proxy for a managed object being referenced from an unmanaged COM client. | counter | `process`
|
||||
`windows_netframework_clrinterop_interop_marshalling_total` | Displays the total number of times arguments and return values have been marshaled from managed to unmanaged code, and vice versa, since the application started. | counter | `process`
|
||||
`windows_netframework_clrinterop_interop_stubs_created_total` | Displays the current number of stubs created by the common language runtime. Stubs are responsible for marshaling arguments and return values from managed to unmanaged code, and vice versa, during a COM interop call or a platform invoke call. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,31 +0,0 @@
|
||||
# netframework_clrjit collector
|
||||
|
||||
The netframework_clrjit collector exposes metrics about the dotnet Just-in-Time compiler.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrjit`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRJit`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrjit_jit_methods_total` | Displays the total number of methods JIT-compiled since the application started. This counter does not include pre-JIT-compiled methods. | counter | `process`
|
||||
`windows_netframework_clrjit_jit_time_percent` | Displays the percentage of time spent in JIT compilation. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase occurs when a method and its dependencies are compiled. | gauge | `process`
|
||||
`windows_netframework_clrjit_jit_standard_failures_total` | Displays the peak number of methods the JIT compiler has failed to compile since the application started. This failure can occur if the MSIL cannot be verified or if there is an internal error in the JIT compiler. | counter | `process`
|
||||
`windows_netframework_clrjit_jit_il_bytes_total` | Displays the total number of Microsoft intermediate language (MSIL) bytes compiled by the just-in-time (JIT) compiler since the application started | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,36 +0,0 @@
|
||||
# netframework_clrloading collector
|
||||
|
||||
The netframework_clrloading collector exposes metrics about the dotnet loader.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrloading`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRLoading`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrloading_loader_heap_size_bytes` | Displays the current size, in bytes, of the memory committed by the class loader across all application domains. Committed memory is the physical space reserved in the disk paging file. | gauge | `process`
|
||||
`windows_netframework_clrloading_appdomains_loaded_current` | Displays the current number of application domains loaded in this application. | gauge | `process`
|
||||
`windows_netframework_clrloading_assemblies_loaded_current` | Displays the current number of assemblies loaded across all application domains in the currently running application. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | gauge | `process`
|
||||
`windows_netframework_clrloading_classes_loaded_current` | Displays the current number of classes loaded in all assemblies. | gauge | `process`
|
||||
`windows_netframework_clrloading_appdomains_loaded_total` | Displays the peak number of application domains loaded since the application started. | counter | `process`
|
||||
`windows_netframework_clrloading_appdomains_unloaded_total` | Displays the total number of application domains unloaded since the application started. If an application domain is loaded and unloaded multiple times, this counter increments each time the application domain is unloaded. | counter | `process`
|
||||
`windows_netframework_clrloading_assemblies_loaded_total` | Displays the total number of assemblies loaded since the application started. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | counter | `process`
|
||||
`windows_netframework_clrloading_classes_loaded_total` | Displays the cumulative number of classes loaded in all assemblies since the application started. | counter | `process`
|
||||
`windows_netframework_clrloading_class_load_failures_total` | Displays the peak number of classes that have failed to load since the application started. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,34 +0,0 @@
|
||||
# netframework_clrlocksandthreads collector
|
||||
|
||||
The netframework_clrlocksandthreads collector exposes metrics about locks and threads in dotnet applications.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrlocksandthreads`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrlocksandthreads_current_queue_length` | Displays the total number of threads that are currently waiting to acquire a managed lock in the application. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_current_logical_threads` | Displays the number of current managed thread objects in the application. This counter maintains the count of both running and stopped threads. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_physical_threads_current` | Displays the number of native operating system threads created and owned by the common language runtime to act as underlying threads for managed thread objects. This counter's value does not include the threads used by the runtime in its internal operations; it is a subset of the threads in the operating system process. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_recognized_threads_current` | Displays the number of threads that are currently recognized by the runtime. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_recognized_threads_total` | Displays the total number of threads that have been recognized by the runtime since the application started. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | counter | `process`
|
||||
`windows_netframework_clrlocksandthreads_queue_length_total` | Displays the total number of threads that waited to acquire a managed lock since the application started. | counter | `process`
|
||||
`windows_netframework_clrlocksandthreads_contentions_total` | Displays the total number of times that threads in the runtime have attempted to acquire a managed lock unsuccessfully. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,39 +0,0 @@
|
||||
# netframework_clrmemory collector
|
||||
|
||||
The netframework_clrmemory collector exposes metrics about memory in dotnet applications.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrmemory`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRMemory`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrmemory_allocated_bytes_total` | Displays the total number of bytes allocated on the garbage collection heap. | counter | `process`
|
||||
`windows_netframework_clrmemory_finalization_survivors` | Displays the number of garbage-collected objects that survive a collection because they are waiting to be finalized. | gauge | `process`
|
||||
`windows_netframework_clrmemory_heap_size_bytes` | Displays the maximum bytes that can be allocated; it does not indicate the current number of bytes allocated. | gauge | `process`
|
||||
`windows_netframework_clrmemory_promoted_bytes` | Displays the bytes that were promoted from the generation to the next one during the last GC. Memory is promoted when it survives a garbage collection. | gauge | `process`
|
||||
`windows_netframework_clrmemory_number_gc_handles` | Displays the current number of garbage collection handles in use. Garbage collection handles are handles to resources external to the common language runtime and the managed environment. | gauge | `process`
|
||||
`windows_netframework_clrmemory_collections_total` | Displays the number of times the generation objects are garbage collected since the application started. | counter | `process`
|
||||
`windows_netframework_clrmemory_induced_gc_total` | Displays the peak number of times garbage collection was performed because of an explicit call to GC.Collect. | counter | `process`
|
||||
`windows_netframework_clrmemory_number_pinned_objects` | Displays the number of pinned objects encountered in the last garbage collection. | gauge | `process`
|
||||
`windows_netframework_clrmemory_number_sink_blocksinuse` | Displays the current number of synchronization blocks in use. Synchronization blocks are per-object data structures allocated for storing synchronization information. They hold weak references to managed objects and must be scanned by the garbage collector. | gauge | `process`
|
||||
`windows_netframework_clrmemory_committed_bytes` | Displays the amount of virtual memory, in bytes, currently committed by the garbage collector. Committed memory is the physical memory for which space has been reserved in the disk paging file. | gauge | `process`
|
||||
`windows_netframework_clrmemory_reserved_bytes` | Displays the amount of virtual memory, in bytes, currently reserved by the garbage collector. Reserved memory is the virtual memory space reserved for the application when no disk or main memory pages have been used. | gauge | `process`
|
||||
`windows_netframework_clrmemory_gc_time_percent` | Displays the percentage of time that was spent performing a garbage collection in the last sample. | gauge | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,33 +0,0 @@
|
||||
# netframework_clrremoting collector
|
||||
|
||||
The netframework_clrremoting collector exposes metrics about dotnet remoting.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrremoting`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRRemoting`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrremoting_channels_total` | Displays the total number of remoting channels registered across all application domains since application started. | counter | `process`
|
||||
`windows_netframework_clrremoting_context_bound_classes_loaded` | Displays the current number of context-bound classes that are loaded. | gauge | `process`
|
||||
`windows_netframework_clrremoting_context_bound_objects_total` | Displays the total number of context-bound objects allocated. | counter | `process`
|
||||
`windows_netframework_clrremoting_context_proxies_total` | Displays the total number of remoting proxy objects in this process since it started. | counter | `process`
|
||||
`windows_netframework_clrremoting_contexts` | Displays the current number of remoting contexts in the application. | gauge | `process`
|
||||
`windows_netframework_clrremoting_remote_calls_total` | Displays the total number of remote procedure calls invoked since the application started. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,31 +0,0 @@
|
||||
# netframework_clrsecurity collector
|
||||
|
||||
The netframework_clrsecurity collector exposes metrics about security checks in dotnet applications
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrsecurity`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRSecurity`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrsecurity_link_time_checks_total` | Displays the total number of link-time code access security checks since the application started. | counter | `process`
|
||||
`windows_netframework_clrsecurity_rt_checks_time_percent` | Displays the percentage of time spent performing runtime code access security checks in the last sample. | gauge | `process`
|
||||
`windows_netframework_clrsecurity_stack_walk_depth` | Displays the depth of the stack during that last runtime code access security check. | gauge | `process`
|
||||
`windows_netframework_clrsecurity_runtime_checks_total` | Displays the total number of runtime code access security checks performed since the application started. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -14,58 +14,26 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_os_info` | Contains full product name & version in labels. Note that the `major_version` for Windows 11 is "10"; a build number greater than 22000 represents Windows 11. | gauge | `product`, `version`, `major_version`, `minor_version`, `build_number`
|
||||
`windows_os_paging_limit_bytes` | Total number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | None
|
||||
`windows_os_paging_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | None
|
||||
`windows_os_physical_memory_free_bytes` | Bytes of physical memory currently unused and available | gauge | None
|
||||
`windows_os_time` | Current time as reported by the operating system, in [Unix time](https://en.wikipedia.org/wiki/Unix_time). See [time.Unix()](https://golang.org/pkg/time/#Unix) for details | gauge | None
|
||||
`windows_os_timezone` | Current timezone as reported by the operating system. See [time.Zone()](https://golang.org/pkg/time/#Time.Zone) for details | gauge | `timezone`
|
||||
`windows_os_processes` | Number of process contexts currently loaded or running on the operating system | gauge | None
|
||||
`windows_os_processes_limit` | Maximum number of process contexts the operating system can support. The default value set by the provider is 4294967295 (0xFFFFFFFF) | gauge | None
|
||||
`windows_os_process_memory_limit_bytes` | Maximum number of bytes of memory that can be allocated to a process | gauge | None
|
||||
`windows_os_users` | Number of user sessions for which the operating system is storing state information currently. For a list of current active logon sessions, see [`logon`](collector.logon.md) | gauge | None
|
||||
`windows_os_virtual_memory_bytes` | Bytes of virtual memory | gauge | None
|
||||
`windows_os_visible_memory_bytes` | Total bytes of physical memory available to the operating system. This value does not necessarily indicate the true amount of physical memory, but what is reported to the operating system as available to it | gauge | None
|
||||
`windows_os_virtual_memory_free_bytes` | Bytes of virtual memory currently unused and available | gauge | None
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|------------------------------------------------------------------------|
|
||||
| `windows_os_info` | Contains full product name & version in labels. Note that the `major_version` for Windows 11 is "10"; a build number greater than 22000 represents Windows 11. | gauge | `product`, `version`, `major_version`, `minor_version`, `build_number` |
|
||||
| `windows_os_paging_limit_bytes` | Total number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | None |
|
||||
| `windows_os_paging_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | None |
|
||||
|
||||
|
||||
### Example metric
|
||||
Show current number of processes
|
||||
|
||||
```
|
||||
windows_os_processes{instance="localhost"}
|
||||
# HELP windows_os_hostname Labelled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain
|
||||
# TYPE windows_os_hostname gauge
|
||||
windows_os_hostname{domain="",fqdn="PC",hostname="PC"} 1
|
||||
# HELP windows_os_info Contains full product name & version in labels. Note that the "major_version" for Windows 11 is \\"10\\"; a build number greater than 22000 represents Windows 11.
|
||||
# TYPE windows_os_info gauge
|
||||
windows_os_info{build_number="19045",major_version="10",minor_version="0",product="Windows 10 Pro",revision="4842",version="10.0.19045"} 1
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
Find all devices not set to UTC timezone
|
||||
```
|
||||
windows_os_timezone{timezone != "UTC"}
|
||||
```
|
||||
|
||||
Show memory usage for instance (%)
|
||||
```
|
||||
100 - 100 * windows_os_physical_memory_free_bytes{instance="localhost"} / windows_cs_physical_memory_bytes{instance="localhost"}
|
||||
```
|
||||
_This collector does not yet have useful queries, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
**prometheus.rules**
|
||||
```yaml
|
||||
# Alert on hosts that have exhausted all available physical memory
|
||||
- alert: MemoryExhausted
|
||||
expr: windows_os_physical_memory_free_bytes == 0
|
||||
for: 10m
|
||||
labels:
|
||||
severity: high
|
||||
annotations:
|
||||
summary: "Host {{ $labels.instance }} is out of memory"
|
||||
description: "{{ $labels.instance }} has exhausted all available physical memory"
|
||||
|
||||
# Alert on hosts with greater than 90% memory usage
|
||||
- alert: MemoryLow
|
||||
expr: 100 - 100 * windows_os_physical_memory_free_bytes / windows_cs_physical_memory_bytes > 90
|
||||
for: 10m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Memory usage for host {{ $labels.instance }} is greater than 90%"
|
||||
```
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
114
docs/collector.perfdata.md
Normal file
114
docs/collector.perfdata.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Perfdata collector
|
||||
|
||||
The perfdata collector exposes any configured metric.
|
||||
|
||||
| | |
|
||||
|---------------------|-------------------------|
|
||||
| Metric name prefix | `perfdata` |
|
||||
| Data source | Performance Data Helper |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
|
||||
### `--collector.perfdata.objects`
|
||||
|
||||
Objects is a list of objects to collect metrics from. The value takes the form of a JSON array of strings. YAML is also supported.
|
||||
|
||||
The collector supports only english named counter. Localized counter-names are not supported.
|
||||
|
||||
#### Schema
|
||||
|
||||
YAML:
|
||||
```yaml
|
||||
- object: "Processor Information"
|
||||
instances: ["*"]
|
||||
instance_label: "core"
|
||||
counters:
|
||||
"% Processor Time": {}
|
||||
- object: "Memory"
|
||||
counters:
|
||||
"Cache Faults/sec":
|
||||
type: "counter"
|
||||
```
|
||||
|
||||
JSON:
|
||||
|
||||
```json
|
||||
[
|
||||
{"object":"Processor Information","instance_label": "core","instances":["*"],"counters": {"% Processor Time": {}}},
|
||||
{"object":"Memory","counters": {"Cache Faults/sec": {"type": "counter"}}}
|
||||
]
|
||||
```
|
||||
|
||||
#### name
|
||||
|
||||
ObjectName is the Object to query for, like Processor, DirectoryServices, LogicalDisk or similar.
|
||||
|
||||
The collector supports only english named counter. Localized counter-names are not supported.
|
||||
|
||||
#### instances
|
||||
|
||||
The instances key (this is an array) declares the instances of a counter you would like returned, it can be one or more values.
|
||||
|
||||
Example: Instances = `["C:","D:","E:"]`
|
||||
|
||||
This will return only for the instances C:, D: and E: where relevant. To get all instances of a Counter, use `["*"]` only.
|
||||
|
||||
Some Objects like `Memory` do not have instances to select from at all. In this case, the `instances` key can be omitted.
|
||||
|
||||
#### counters
|
||||
|
||||
The Counters key (this is an object) declares the counters of the ObjectName you would like returned, it can also be one or more values.
|
||||
|
||||
Example: Counters = `{"% Idle Time": {}, "% Disk Read Time": {}, "% Disk Write Time": {}}`
|
||||
|
||||
This must be specified for every counter you want the results. Wildcards are not supported.
|
||||
|
||||
#### counters Sub-Schema
|
||||
|
||||
##### type
|
||||
|
||||
This key is optional. It indicates the type of the counter. The value can be `counter` or `gauge`.
|
||||
If not specified, the windows_exporter will try to determine the type based on the counter type.
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
# HELP windows_perfdata_memory_cache_faults_sec
|
||||
# TYPE windows_perfdata_memory_cache_faults_sec counter
|
||||
windows_perfdata_memory_cache_faults_sec 2.369977e+07
|
||||
# HELP windows_perfdata_processor_information__processor_time
|
||||
# TYPE windows_perfdata_processor_information__processor_time gauge
|
||||
windows_perfdata_processor_information__processor_time{instance="0,0"} 1.7259640625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,1"} 1.7576796875e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,10"} 2.2704234375e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,11"} 2.3069296875e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,12"} 2.3302265625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,13"} 2.32851875e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,14"} 2.3282421875e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,15"} 2.3271234375e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,16"} 2.329590625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,17"} 2.32800625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,18"} 2.3194359375e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,19"} 2.32380625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,2"} 1.954765625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,20"} 2.3259765625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,21"} 2.3268515625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,22"} 2.3301765625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,23"} 2.3264328125e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,3"} 1.94745625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,4"} 2.2011453125e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,5"} 2.27244375e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,6"} 2.25501875e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,7"} 2.2995265625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,8"} 2.2929890625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,9"} 2.313540625e+11
|
||||
windows_perfdata_processor_information__processor_time{instance="0,_Total"} 2.23009459635e+11
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
The perfdata collector returns metrics based on the user configuration.
|
||||
The metrics are named based on the object name and the counter name.
|
||||
The instance name is added as a label to the metric.
|
||||
@@ -37,11 +37,6 @@ Enables IIS process name queries. IIS process names are combined with their app
|
||||
|
||||
Disabled by default, and can be enabled with `--collector.process.iis=true`.
|
||||
|
||||
### `--collector.process.report-owner`
|
||||
|
||||
Enables reporting of the process owner. This is a potentially expensive operation.
|
||||
|
||||
Disabled by default, and can be enabled with `--collector.process.report-owner`.
|
||||
|
||||
### Example
|
||||
To match all firefox processes: `--collector.process.include="firefox.*"`.
|
||||
@@ -74,23 +69,24 @@ w3wp_Test
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------------------------------------------------------|
|
||||
| `windows_process_start_time` | Time of process start | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_cpu_time_total` | Returns elapsed time that all of the threads of this process used the processor to execute instructions by mode (privileged, user). An instruction is the basic unit of execution in a computer, a thread is the object that executes instructions, and a process is the object created when a program is run. Code executed to handle some hardware interrupts and trap conditions is included in this count. | counter | `process`, `process_id`, `creating_process_id`, `owner`, `mode` |
|
||||
| `windows_process_handles` | Total number of handles the process has open. This number is the sum of the handles currently open by each thread in the process. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_io_bytes_total` | Bytes issued to I/O operations in different modes (read, write, other). This property counts all I/O activity generated by the process to include file, network, and device I/Os. Read and write mode includes data operations; other mode includes those that do not involve data, such as control operations. | counter | `process`, `process_id`, `creating_process_id`, `owner`, `mode` |
|
||||
| `windows_process_io_operations_total` | I/O operations issued in different modes (read, write, other). This property counts all I/O activity generated by the process to include file, network, and device I/Os. Read and write mode includes data operations; other mode includes those that do not involve data, such as control operations. | counter | `process`, `process_id`, `creating_process_id`, `owner`, `mode` |
|
||||
| `windows_process_page_faults_total` | Page faults by the threads executing in this process. A page fault occurs when a thread refers to a virtual memory page that is not in its working set in main memory. This can cause the page not to be fetched from disk if it is on the standby list and hence already in main memory, or if it is in use by another process with which the page is shared. | counter | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_page_file_bytes` | Current number of bytes this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and lack of space in paging files can prevent other processes from allocating memory. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_pool_bytes` | Pool Bytes is the last observed number of bytes in the paged or nonpaged pool. The nonpaged pool is an area of system memory (physical memory used by the operating system) for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated. The paged pool is an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. Nonpaged pool bytes is calculated differently than paged pool bytes, so it might not equal the total of paged pool bytes. | gauge | `process`, `process_id`, `creating_process_id`, `owner`, `pool` |
|
||||
| `windows_process_priority_base` | Current base priority of this process. Threads within a process can raise and lower their own base priority relative to the process base priority of the process. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_private_bytes` | Current number of bytes this process has allocated that cannot be shared with other processes. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_threads` | Number of threads currently active in this process. An instruction is the basic unit of execution in a processor, and a thread is the object that executes instructions. Every running process has at least one thread. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_virtual_bytes` | Current size, in bytes, of the virtual address space that the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite and, by using too much, the process can limit its ability to load libraries. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_working_set_private_bytes` | Size of the working set, in bytes, that is use for this process only and not shared nor shareable by other processes. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_working_set_peak_bytes` | Maximum size, in bytes, of the Working Set of this process at any point in time. The Working Set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the Working Set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from Working Sets. If they are needed they will then be soft-faulted back into the Working Set before they leave main memory. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| `windows_process_working_set_bytes` | Maximum number of bytes in the working set of this process at any point in time. The working set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the working set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from working sets. If they are needed, they are then soft-faulted back into the working set before they leave main memory. | gauge | `process`, `process_id`, `creating_process_id`, `owner` |
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|---------------------------------------------------------------------------------------|
|
||||
| `windows_process_info` | A metric with a constant '1' value labeled with process information | gauge | `process`, `process_id`, `creating_process_id`, `process_group_id`,`owner`, `cmdline` |
|
||||
| `windows_process_start_time` | Time of process start | gauge | `process`, `process_id` |
|
||||
| `windows_process_cpu_time_total` | Returns elapsed time that all of the threads of this process used the processor to execute instructions by mode (privileged, user). An instruction is the basic unit of execution in a computer, a thread is the object that executes instructions, and a process is the object created when a program is run. Code executed to handle some hardware interrupts and trap conditions is included in this count. | counter | `process`, `process_id`, `mode` |
|
||||
| `windows_process_handles` | Total number of handles the process has open. This number is the sum of the handles currently open by each thread in the process. | gauge | `process`, `process_id` |
|
||||
| `windows_process_io_bytes_total` | Bytes issued to I/O operations in different modes (read, write, other). This property counts all I/O activity generated by the process to include file, network, and device I/Os. Read and write mode includes data operations; other mode includes those that do not involve data, such as control operations. | counter | `process`, `process_id`, `mode` |
|
||||
| `windows_process_io_operations_total` | I/O operations issued in different modes (read, write, other). This property counts all I/O activity generated by the process to include file, network, and device I/Os. Read and write mode includes data operations; other mode includes those that do not involve data, such as control operations. | counter | `process`, `process_id`, `mode` |
|
||||
| `windows_process_page_faults_total` | Page faults by the threads executing in this process. A page fault occurs when a thread refers to a virtual memory page that is not in its working set in main memory. This can cause the page not to be fetched from disk if it is on the standby list and hence already in main memory, or if it is in use by another process with which the page is shared. | counter | `process`, `process_id` |
|
||||
| `windows_process_page_file_bytes` | Current number of bytes this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and lack of space in paging files can prevent other processes from allocating memory. | gauge | `process`, `process_id` |
|
||||
| `windows_process_pool_bytes` | Pool Bytes is the last observed number of bytes in the paged or nonpaged pool. The nonpaged pool is an area of system memory (physical memory used by the operating system) for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated. The paged pool is an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. Nonpaged pool bytes is calculated differently than paged pool bytes, so it might not equal the total of paged pool bytes. | gauge | `process`, `process_id`, `pool` |
|
||||
| `windows_process_priority_base` | Current base priority of this process. Threads within a process can raise and lower their own base priority relative to the process base priority of the process. | gauge | `process`, `process_id` |
|
||||
| `windows_process_private_bytes` | Current number of bytes this process has allocated that cannot be shared with other processes. | gauge | `process`, `process_id` |
|
||||
| `windows_process_threads` | Number of threads currently active in this process. An instruction is the basic unit of execution in a processor, and a thread is the object that executes instructions. Every running process has at least one thread. | gauge | `process`, `process_id` |
|
||||
| `windows_process_virtual_bytes` | Current size, in bytes, of the virtual address space that the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite and, by using too much, the process can limit its ability to load libraries. | gauge | `process`, `process_id` |
|
||||
| `windows_process_working_set_private_bytes` | Size of the working set, in bytes, that is use for this process only and not shared nor shareable by other processes. | gauge | `process`, `process_id` |
|
||||
| `windows_process_working_set_peak_bytes` | Maximum size, in bytes, of the Working Set of this process at any point in time. The Working Set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the Working Set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from Working Sets. If they are needed they will then be soft-faulted back into the Working Set before they leave main memory. | gauge | `process`, `process_id` |
|
||||
| `windows_process_working_set_bytes` | Maximum number of bytes in the working set of this process at any point in time. The working set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the working set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from working sets. If they are needed, they are then soft-faulted back into the working set before they leave main memory. | gauge | `process`, `process_id` |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
@@ -2,47 +2,24 @@
|
||||
|
||||
The service collector exposes metrics about Windows Services
|
||||
|
||||
The collector exists in 2 different version. Version 1 is using WMI to query all services and is able to provide additional
|
||||
information. Version 2 is a more efficient solution by directly connecting to the service manager, but is not able to
|
||||
provide additional information like `run_as` or start configuration
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collector.service.services-where`
|
||||
|
||||
A WMI filter on which services to include. Recommended to keep down number of returned metrics.
|
||||
|
||||
Example: `--collector.service.services-where="Name='windows_exporter'"`
|
||||
|
||||
Example config win_exporter.yml for multiple services: `services-where: Name='SQLServer' OR Name='Couchbase' OR Name='Spooler' OR Name='ActiveMQ'`
|
||||
|
||||
### `--collector.service.use-api`
|
||||
|
||||
Uses API calls instead of WMI for performance optimization. **Note** the previous flag (`--collector.service.services-where`) won't have any effect on this mode.
|
||||
|
||||
### `--collector.service.v2`
|
||||
|
||||
Version 2 of the service collector. Is using API calls for performance optimization. **Note** the previous flag (`--collector.service.services-where`) won't have any effect on this mode.
|
||||
For additional performance reasons, it doesn't provide any additional information like `run_as` or start configuration.
|
||||
|
||||
# collector V1
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `service`
|
||||
Classes | [`Win32_Service`](https://msdn.microsoft.com/en-us/library/aa394418(v=vs.85).aspx)
|
||||
Classes | none
|
||||
Enabled by default? | Yes
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_service_info` | Contains service information in labels, constant 1 | gauge | name, display_name, process_id, run_as
|
||||
`windows_service_state` | The state of the service, 1 if the current state, 0 otherwise | gauge | name, state
|
||||
`windows_service_start_mode` | The start mode of the service, 1 if the current start mode, 0 otherwise | gauge | name, start_mode
|
||||
`windows_service_status` | The status of the service, 1 if the current status, 0 otherwise | gauge | name, status
|
||||
|
||||
For the values of the `state`, `start_mode`, `status` and `run_as` labels, see below.
|
||||
| Name | Description | Type | Labels |
|
||||
|------------------------------|-----------------------------------------------------------------------------------------------|-------|---------------------------------------|
|
||||
| `windows_service_info` | Contains service information run as user in labels, constant 1 | gauge | name, display_name, path_name, run_as |
|
||||
| `windows_service_start_mode` | The start mode of the service, 1 if the current start mode, 0 otherwise | gauge | name, start_mode |
|
||||
| `windows_service_state` | The state of the service, 1 if the current state, 0 otherwise | gauge | name, state |
|
||||
| `windows_service_process` | Process of started service. The value is the creation time of the process as a unix timestamp | gauge | name, process_id |
|
||||
|
||||
### States
|
||||
|
||||
@@ -65,81 +42,50 @@ A service can have the following start modes:
|
||||
- `manual`
|
||||
- `disabled`
|
||||
|
||||
### Status (not available in API mode)
|
||||
|
||||
A service can have any of the following statuses:
|
||||
- `ok`
|
||||
- `error`
|
||||
- `degraded`
|
||||
- `unknown`
|
||||
- `pred fail`
|
||||
- `starting`
|
||||
- `stopping`
|
||||
- `service`
|
||||
- `stressed`
|
||||
- `nonrecover`
|
||||
- `no contact`
|
||||
- `lost comm`
|
||||
|
||||
Note that there is some overlap with service state.
|
||||
|
||||
### Run As
|
||||
|
||||
Account name under which a service runs. Depending on the service type, the account name may be in the form of "DomainName\Username" or UPN format ("Username@DomainName").
|
||||
|
||||
It corresponds to the `StartName` attribute of the `Win32_Service` class.
|
||||
`StartName` attribute can be NULL and in such case the label is reported as an empty string. Notice that if the attribute is NULL the service is logged on as the `LocalSystem` account or, for kernel or system-level drive, it runs with a default object name created by the I/O system based on the service name, for example, DWDOM\Admin.
|
||||
|
||||
### Example metric
|
||||
Lists the services that have a 'disabled' start mode.
|
||||
```
|
||||
windows_service_start_mode{exported_name=~"(mssqlserver|sqlserveragent)",start_mode="disabled"}
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
Counts the number of Microsoft SQL Server/Agent Processes
|
||||
```
|
||||
count(windows_service_state{exported_name=~"(sqlserveragent|mssqlserver)",state="running"})
|
||||
```
|
||||
|
||||
# collector V2
|
||||
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `service`
|
||||
Classes | none
|
||||
Enabled by default? | No
|
||||
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_service_state` | The state of the service, 1 if the current state, 0 otherwise | gauge | name, display_name, state
|
||||
|
||||
### States
|
||||
|
||||
A service can be in the following states:
|
||||
- `stopped`
|
||||
- `start pending`
|
||||
- `stop pending`
|
||||
- `running`
|
||||
- `continue pending`
|
||||
- `pause pending`
|
||||
- `paused`
|
||||
- `unknown`
|
||||
|
||||
### Example metric
|
||||
|
||||
```
|
||||
windows_service_state{display_name="Declared Configuration(DC) service",name="dcsvc",status="continue pending"} 0
|
||||
windows_service_state{display_name="Declared Configuration(DC) service",name="dcsvc",status="pause pending"} 0
|
||||
windows_service_state{display_name="Declared Configuration(DC) service",name="dcsvc",status="paused"} 0
|
||||
windows_service_state{display_name="Declared Configuration(DC) service",name="dcsvc",status="running"} 0
|
||||
windows_service_state{display_name="Declared Configuration(DC) service",name="dcsvc",status="start pending"} 0
|
||||
windows_service_state{display_name="Declared Configuration(DC) service",name="dcsvc",status="stop pending"} 0
|
||||
windows_service_state{display_name="Declared Configuration(DC) service",name="dcsvc",status="stopped"} 1
|
||||
# HELP windows_service_info A metric with a constant '1' value labeled with service information
|
||||
# TYPE windows_service_info gauge
|
||||
windows_service_info{display_name="Declared Configuration(DC) service",name="dcsvc",path_name="C:\\WINDOWS\\system32\\svchost.exe -k netsvcs -p",run_as="LocalSystem"} 1
|
||||
windows_service_info{display_name="Designs",name="Themes",path_name="C:\\WINDOWS\\System32\\svchost.exe -k netsvcs -p",run_as="LocalSystem"} 1
|
||||
# HELP windows_service_process Process of started service. The value is the creation time of the process as a unix timestamp.
|
||||
# TYPE windows_service_process gauge
|
||||
windows_service_process{name="Themes",process_id="2856"} 1.7244891e+09
|
||||
# HELP windows_service_start_mode The start mode of the service (StartMode)
|
||||
# TYPE windows_service_start_mode gauge
|
||||
windows_service_start_mode{name="Themes",start_mode="auto"} 1
|
||||
windows_service_start_mode{name="Themes",start_mode="boot"} 0
|
||||
windows_service_start_mode{name="Themes",start_mode="disabled"} 0
|
||||
windows_service_start_mode{name="Themes",start_mode="manual"} 0
|
||||
windows_service_start_mode{name="Themes",start_mode="system"} 0
|
||||
windows_service_start_mode{name="dcsvc",start_mode="auto"} 0
|
||||
windows_service_start_mode{name="dcsvc",start_mode="boot"} 0
|
||||
windows_service_start_mode{name="dcsvc",start_mode="disabled"} 0
|
||||
windows_service_start_mode{name="dcsvc",start_mode="manual"} 1
|
||||
windows_service_start_mode{name="dcsvc",start_mode="system"} 0
|
||||
# HELP windows_service_state The state of the service (State)
|
||||
# TYPE windows_service_state gauge
|
||||
windows_service_state{name="Themes",state="continue pending"} 0
|
||||
windows_service_state{name="Themes",state="pause pending"} 0
|
||||
windows_service_state{name="Themes",state="paused"} 0
|
||||
windows_service_state{name="Themes",state="running"} 1
|
||||
windows_service_state{name="Themes",state="start pending"} 0
|
||||
windows_service_state{name="Themes",state="stop pending"} 0
|
||||
windows_service_state{name="Themes",state="stopped"} 0
|
||||
windows_service_state{name="dcsvc",state="continue pending"} 0
|
||||
windows_service_state{name="dcsvc",state="pause pending"} 0
|
||||
windows_service_state{name="dcsvc",state="paused"} 0
|
||||
windows_service_state{name="dcsvc",state="running"} 0
|
||||
windows_service_state{name="dcsvc",state="start pending"} 0
|
||||
windows_service_state{name="dcsvc",state="stop pending"} 0
|
||||
windows_service_state{name="dcsvc",state="stopped"} 1
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
@@ -163,8 +109,8 @@ groups:
|
||||
labels:
|
||||
severity: high
|
||||
annotations:
|
||||
summary: "Service {{ $labels.exported_name }} down"
|
||||
description: "Service {{ $labels.exported_name }} on instance {{ $labels.instance }} has been down for more than 3 minutes."
|
||||
summary: "Service {{ $labels.name }} down"
|
||||
description: "Service {{ $labels.name }} on instance {{ $labels.instance }} has been down for more than 3 minutes."
|
||||
|
||||
# Sends an alert when the 'mssqlserver' service is not in the running state for 3 minutes.
|
||||
- alert: SQL Server DOWN
|
||||
@@ -173,7 +119,7 @@ groups:
|
||||
labels:
|
||||
severity: high
|
||||
annotations:
|
||||
summary: "Service {{ $labels.exported_name }} down"
|
||||
description: "Service {{ $labels.exported_name }} on instance {{ $labels.instance }} has been down for more than 3 minutes."
|
||||
summary: "Service {{ $labels.name }} down"
|
||||
description: "Service {{ $labels.name }} on instance {{ $labels.instance }} has been down for more than 3 minutes."
|
||||
```
|
||||
In this example, `instance` is the target label of the host. So each alert will be processed per host, which is then used in the alert description.
|
||||
|
||||
@@ -5,8 +5,7 @@ The system collector exposes metrics about ...
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `system`
|
||||
Data source | Perflib
|
||||
Classes | [`Win32_PerfRawData_PerfOS_System`](https://web.archive.org/web/20050830140516/http://msdn.microsoft.com/library/en-us/wmisdk/wmi/win32_perfrawdata_perfos_system.asp)
|
||||
Data source | Performance Counters
|
||||
Enabled by default? | Yes
|
||||
|
||||
## Flags
|
||||
@@ -15,14 +14,18 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_system_context_switches_total` | Total number of [context switches](https://en.wikipedia.org/wiki/Context_switch) | counter | None
|
||||
`windows_system_exception_dispatches_total` | Total exceptions dispatched by the system | counter | None
|
||||
`windows_system_processor_queue_length` | Number of threads in the processor queue. There is a single queue for processor time even on computers with multiple processors. | gauge | None
|
||||
`windows_system_system_calls_total` | Total combined calls to Windows NT system service routines by all processes running on the computer | counter | None
|
||||
`windows_system_system_up_time` | Time of last boot of system | gauge | None
|
||||
`windows_system_threads` | Number of Windows system [threads](https://en.wikipedia.org/wiki/Thread_(computing)) | gauge | None
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
|
||||
| `windows_system_context_switches_total` | Total number of [context switches](https://en.wikipedia.org/wiki/Context_switch) | counter | None |
|
||||
| `windows_system_exception_dispatches_total` | Total exceptions dispatched by the system | counter | None |
|
||||
| `windows_system_processes` | Number of process contexts currently loaded or running on the operating system | gauge | None |
|
||||
| `windows_system_process_limit` | The size of the user-mode portion of the virtual address space of the calling process, in bytes. This value depends on the type of process, the type of processor, and the configuration of the operating system. | gauge | None |
|
||||
| `windows_system_processor_queue_length` | Number of threads in the processor queue. There is a single queue for processor time even on computers with multiple processors. | gauge | None |
|
||||
| `windows_system_system_calls_total` | Total combined calls to Windows NT system service routines by all processes running on the computer | counter | None |
|
||||
| `windows_system_system_up_time` | Time of last boot of system | gauge | None |
|
||||
| `windows_system_threads` | Number of Windows system [threads](https://en.wikipedia.org/wiki/Thread_(computing)) | gauge | None |
|
||||
|
||||
|
||||
|
||||
### Example metric
|
||||
Show current number of system threads
|
||||
@@ -30,6 +33,11 @@ Show current number of system threads
|
||||
windows_system_threads{instance="localhost"}
|
||||
```
|
||||
|
||||
Show current number of processes
|
||||
```
|
||||
windows_system_processes{instance="localhost"}
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
Find hosts that have rebooted in the last 24 hours
|
||||
```
|
||||
|
||||
@@ -26,6 +26,7 @@ Name | Description | Type | Labels
|
||||
`windows_tcp_segments_received_total` | Total segments received, including those received in error. This count includes segments received on currently established connections | counter | af
|
||||
`windows_tcp_segments_retransmitted_total` | Total segments retransmitted. That is, segments transmitted that contain one or more previously transmitted bytes | counter | af
|
||||
`windows_tcp_segments_sent_total` | Total segments sent, including those on current connections, but excluding those containing *only* retransmitted bytes | counter | af
|
||||
`windows_tcp_connections_state_count` | Number of TCP connections by state among: CLOSED, LISTENING, SYN_SENT, SYN_RECEIVED, ESTABLISHED, FIN_WAIT1, FIN_WAIT2, CLOSE_WAIT, CLOSING, LAST_ACK, TIME_WAIT, DELETE_TCB | gauge | af
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
# teradici_pcoip collector
|
||||
|
||||
The teradici_pcoip collector exposes metrics relating to Teradici PCoIP sessions
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `teradici_pcoip`
|
||||
Classes | `Win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics`, `Win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_teradici_pcoip_audio_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_audio_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_audio_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_audio_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_audio_tx_bw_limit_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_packets_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_packets_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_rx_packets_lost_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_session_duration_seconds_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_tx_packets_lost_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_active_min_quality` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_apex2800_offload` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_decoder_capability_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_encoded_frames_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_megapixel_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_negative_acks_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_svga_devtap_frames_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_round_trip_latency_ms` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_bw_peak_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_packet_loss_percent` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_packet_loss_percent_base` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_bw_active_limit_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_bw_limit_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_packet_loss_percent` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_packet_loss_percent_base` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_usb_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_usb_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_usb_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_usb_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -19,7 +19,6 @@ None
|
||||
| Name | Description | Type | Labels |
|
||||
|------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------|
|
||||
| `windows_terminal_services_session_info` | Info about active WTS sessions | gauge | host,user,state |
|
||||
| `windows_terminal_services_local_session_count` | Number of local Terminal Services sessions. | gauge | `session` |
|
||||
| `windows_terminal_services_connection_broker_performance_total`* | The total number of connections handled by the Connection Brokers since the service started. | counter | `connection` |
|
||||
| `windows_terminal_services_handles` | Total number of handles currently opened by this process. This number is the sum of the handles currently opened by each thread in this process. | gauge | `session_name` |
|
||||
| `windows_terminal_services_page_fault_total` | Rate at which page faults occur in the threads executing in this process. A page fault occurs when a thread refers to a virtual memory page that is not in its working set in main memory. The page may not be retrieved from disk if it is on the standby list and therefore already in main memory. The page also may not be retrieved if it is in use by another process which shares the page. | counter | `session_name` |
|
||||
|
||||
@@ -6,7 +6,7 @@ The textfile collector exposes metrics from files written by other processes.
|
||||
-|-
|
||||
Metric name prefix | `textfile`
|
||||
Classes | None
|
||||
Enabled by default? | Yes
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
|
||||
@@ -17,14 +17,16 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
|
||||
| `windows_time_clock_frequency_adjustment_ppb_total` | Total adjustment made to the local system clock frequency by W32Time in parts per billion (PPB) units. 1 PPB adjustment implies the system clock was adjusted at a rate of 1 nanosecond per second (1 ns/s). The smallest possible adjustment can vary and is expected to be in the order of 100's of PPB. | counter | None |
|
||||
| `windows_time_computed_time_offset_seconds` | The absolute time offset between the system clock and the chosen time source, as computed by the W32Time service in microseconds. When a new valid sample is available, the computed time is updated with the time offset indicated by the sample. This time is the actual time offset of the local clock. W32Time initiates clock correction by using this offset and updates the computed time in between samples with the remaining time offset that needs to be applied to the local clock. Clock accuracy can be tracked by using this performance counter with a low polling interval (for example, 256 seconds or less) and looking for the counter value to be smaller than the desired clock accuracy limit. | gauge | None |
|
||||
| `windows_time_ntp_client_time_sources` | Active number of NTP Time sources being used by the client. This is a count of active, distinct IP addresses of time servers that are responding to this client's requests. | gauge | None |
|
||||
| `windows_time_ntp_round_trip_delay_seconds` | Total roundtrip delay experienced by the NTP client in receiving a response from the server for the most recent request, in seconds. This is the time elapsed on the NTP client between transmitting a request to the NTP server and receiving a valid response from the server. | gauge | None |
|
||||
| `windows_time_ntp_server_outgoing_responses_total` | Total number of requests responded to by the NTP server. | counter | None |
|
||||
| `windows_time_ntp_server_incoming_requests_total` | Total number of requests received by the NTP server. | counter | None |
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|------------|
|
||||
| `windows_time_clock_frequency_adjustment_ppb_total` | Total adjustment made to the local system clock frequency by W32Time in parts per billion (PPB) units. 1 PPB adjustment implies the system clock was adjusted at a rate of 1 nanosecond per second (1 ns/s). The smallest possible adjustment can vary and is expected to be in the order of 100's of PPB. | counter | None |
|
||||
| `windows_time_computed_time_offset_seconds` | The absolute time offset between the system clock and the chosen time source, as computed by the W32Time service in microseconds. When a new valid sample is available, the computed time is updated with the time offset indicated by the sample. This time is the actual time offset of the local clock. W32Time initiates clock correction by using this offset and updates the computed time in between samples with the remaining time offset that needs to be applied to the local clock. Clock accuracy can be tracked by using this performance counter with a low polling interval (for example, 256 seconds or less) and looking for the counter value to be smaller than the desired clock accuracy limit. | gauge | None |
|
||||
| `windows_time_ntp_client_time_sources` | Active number of NTP Time sources being used by the client. This is a count of active, distinct IP addresses of time servers that are responding to this client's requests. | gauge | None |
|
||||
| `windows_time_ntp_round_trip_delay_seconds` | Total roundtrip delay experienced by the NTP client in receiving a response from the server for the most recent request, in seconds. This is the time elapsed on the NTP client between transmitting a request to the NTP server and receiving a valid response from the server. | gauge | None |
|
||||
| `windows_time_ntp_server_outgoing_responses_total` | Total number of requests responded to by the NTP server. | counter | None |
|
||||
| `windows_time_ntp_server_incoming_requests_total` | Total number of requests received by the NTP server. | counter | None |
|
||||
| `windows_time_current_timestamp_seconds` | Current time as reported by the operating system, in [Unix time](https://en.wikipedia.org/wiki/Unix_time). See [time.Unix()](https://golang.org/pkg/time/#Unix) for details | gauge | None |
|
||||
| `windows_time_timezone` | Current timezone as reported by the operating system. | gauge | `timezone` |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
48
docs/collector.update.md
Normal file
48
docs/collector.update.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# update collector
|
||||
|
||||
The update collector exposes the Windows Update service metrics. Note that the Windows Update service (`wuauserv`) must be running, else metric collection will fail.
|
||||
|
||||
The Windows Update service is responsible for managing the installation of updates for the operating system and other Microsoft software. The service can be configured to automatically download and install updates, or to notify the user when updates are available.
|
||||
|
||||
|
||||
| | |
|
||||
|---------------------|------------------------|
|
||||
| Metric name prefix | `update` |
|
||||
| Data source | Windows Update service |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collector.updates.online`
|
||||
Whether to search for updates online. If set to `false`, the collector will only list updates that are already found by the Windows Update service.
|
||||
Set to `true` to search for updates online, which will take longer to complete.
|
||||
|
||||
### `--collector.updates.scrape-interval`
|
||||
Define the interval of scraping Windows Update information
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------|-----------------------------------------------|-------|-------------------------------|
|
||||
| `windows_updates_pending_info` | Expose information single pending update item | gauge | `category`,`severity`,`title` |
|
||||
| `windows_updates_scrape_query_duration_seconds` | Duration of the last scrape query to the Windows Update API | gauge | |
|
||||
| `windows_updates_scrape_timestamp_seconds` | Timestamp of the last scrape | gauge | |
|
||||
|
||||
### Example metrics
|
||||
```
|
||||
# HELP windows_updates_pending Pending Windows Updates
|
||||
# TYPE windows_updates_pending gauge
|
||||
windows_updates_pending{category="Drivers",severity="",title="Intel Corporation - Bluetooth - 23.60.5.10"} 1
|
||||
# HELP windows_updates_scrape_query_duration_seconds Duration of the last scrape query to the Windows Update API
|
||||
# TYPE windows_updates_scrape_query_duration_seconds gauge
|
||||
windows_updates_scrape_query_duration_seconds 2.8161838
|
||||
# HELP windows_updates_scrape_timestamp_seconds Timestamp of the last scrape
|
||||
# TYPE windows_updates_scrape_timestamp_seconds gauge
|
||||
windows_updates_scrape_timestamp_seconds 1.727539734e+09
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,98 +0,0 @@
|
||||
# vmware_blast collector
|
||||
|
||||
The vmware_blast collector exposes metrics relating to VMware Blast sessions
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `vmware_blast`
|
||||
Classes | `Win32_PerfRawData_Counters_VMwareBlastAudioCounters`,`Win32_PerfRawData_Counters_VMwareBlastCDRCounters`,`Win32_PerfRawData_Counters_VMwareBlastClipboardCounters`,`Win32_PerfRawData_Counters_VMwareBlastHTML5MMRCounters`,`Win32_PerfRawData_Counters_VMwareBlastImagingCounters`,`Win32_PerfRawData_Counters_VMwareBlastRTAVCounters`,`Win32_PerfRawData_Counters_VMwareBlastSerialPortandScannerCounters`,`Win32_PerfRawData_Counters_VMwareBlastSessionCounters`,`Win32_PerfRawData_Counters_VMwareBlastSkypeforBusinessControlCounters`,`Win32_PerfRawData_Counters_VMwareBlastThinPrintCounters`,`Win32_PerfRawData_Counters_VMwareBlastUSBCounters`,`Win32_PerfRawData_Counters_VMwareBlastWindowsMediaMMRCounters`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Some of these metrics may not be collected, depending on the installation options chosen when installing the Horizon agent
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_vmware_blast_audio_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_audio_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_audio_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_audio_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_dirty_frames_per_second` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_fbc_rate` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_frames_per_second` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_poll_rate` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_dirty_frames_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_fbc_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_frames_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_poll_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_automatic_reconnect_count_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_received_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_received_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_transmitted_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_transmitted_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_estimated_bandwidth_uplink` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_instantaneous_received_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_instantaneous_received_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_instantaneous_transmitted_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_instantaneous_transmitted_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_jitter_uplink` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_packet_loss_uplink` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_rtt` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -4,7 +4,7 @@ collectors:
|
||||
enabled: cpu,cs,logical_disk,net,os,service,system
|
||||
collector:
|
||||
service:
|
||||
services-where: Name='windows_exporter'
|
||||
include: "windows_exporter"
|
||||
scheduled_task:
|
||||
include: /Microsoft/.+
|
||||
log:
|
||||
|
||||
371
exporter.go
371
exporter.go
@@ -7,12 +7,12 @@ package main
|
||||
//goland:noinspection GoUnsortedImport
|
||||
//nolint:gofumpt
|
||||
import (
|
||||
// Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts.
|
||||
"github.com/prometheus-community/windows_exporter/pkg/initiate"
|
||||
"github.com/prometheus-community/windows_exporter/internal/initiate"
|
||||
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
@@ -24,70 +24,42 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/internal/config"
|
||||
"github.com/prometheus-community/windows_exporter/internal/httphandler"
|
||||
"github.com/prometheus-community/windows_exporter/internal/log"
|
||||
"github.com/prometheus-community/windows_exporter/internal/log/flag"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/config"
|
||||
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/log/flag"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus/common/version"
|
||||
"github.com/prometheus/exporter-toolkit/web"
|
||||
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Same struct prometheus uses for their /version endpoint.
|
||||
// Separate copy to avoid pulling all of prometheus as a dependency.
|
||||
type prometheusVersion struct {
|
||||
Version string `json:"version"`
|
||||
Revision string `json:"revision"`
|
||||
Branch string `json:"branch"`
|
||||
BuildUser string `json:"buildUser"`
|
||||
BuildDate string `json:"buildDate"`
|
||||
GoVersion string `json:"goVersion"`
|
||||
}
|
||||
|
||||
// Mapping of priority names to uin32 values required by windows.SetPriorityClass.
|
||||
var priorityStringToInt = map[string]uint32{
|
||||
"realtime": windows.REALTIME_PRIORITY_CLASS,
|
||||
"high": windows.HIGH_PRIORITY_CLASS,
|
||||
"abovenormal": windows.ABOVE_NORMAL_PRIORITY_CLASS,
|
||||
"normal": windows.NORMAL_PRIORITY_CLASS,
|
||||
"belownormal": windows.BELOW_NORMAL_PRIORITY_CLASS,
|
||||
"low": windows.IDLE_PRIORITY_CLASS,
|
||||
}
|
||||
|
||||
func setPriorityWindows(pid int, priority uint32) error {
|
||||
// https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
||||
handle, err := windows.OpenProcess(
|
||||
windows.STANDARD_RIGHTS_REQUIRED|windows.SYNCHRONIZE|windows.SPECIFIC_RIGHTS_ALL,
|
||||
false, uint32(pid),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = windows.SetPriorityClass(handle, priority); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = windows.CloseHandle(handle); err != nil {
|
||||
return fmt.Errorf("failed to close handle: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
exitCode := run()
|
||||
|
||||
// If we are running as a service, we need to signal the service control manager that we are done.
|
||||
if !initiate.IsService {
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
initiate.ExitCodeCh <- exitCode
|
||||
|
||||
// Wait for the service control manager to signal that we are done.
|
||||
<-initiate.StopCh
|
||||
}
|
||||
|
||||
func run() int {
|
||||
app := kingpin.New("windows_exporter", "A metrics collector for Windows.")
|
||||
|
||||
var (
|
||||
configFile = app.Flag(
|
||||
"config.file",
|
||||
"YAML configuration file to use. Values set in this file will be overridden by CLI flags.",
|
||||
).String()
|
||||
insecure_skip_verify = app.Flag(
|
||||
insecureSkipVerify = app.Flag(
|
||||
"config.file.insecure-skip-verify",
|
||||
"Skip TLS verification in loading YAML configuration.",
|
||||
).Default("false").Bool()
|
||||
@@ -126,8 +98,8 @@ func main() {
|
||||
).Default("normal").String()
|
||||
)
|
||||
|
||||
winlogConfig := &winlog.Config{}
|
||||
flag.AddFlags(app, winlogConfig)
|
||||
logConfig := &log.Config{}
|
||||
flag.AddFlags(app, logConfig)
|
||||
|
||||
app.Version(version.Print("windows_exporter"))
|
||||
app.HelpFlag.Short('h')
|
||||
@@ -137,25 +109,41 @@ func main() {
|
||||
|
||||
// Load values from configuration file(s). Executable flags must first be parsed, in order
|
||||
// to load the specified file(s).
|
||||
kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||
logger, err := winlog.New(winlogConfig)
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("err", err)
|
||||
os.Exit(1)
|
||||
if _, err := app.Parse(os.Args[1:]); err != nil {
|
||||
//nolint:sloglint // we do not have an logger yet
|
||||
slog.Error("Failed to parse CLI args",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_ = level.Debug(logger).Log("msg", "Logging has Started")
|
||||
logger, err := log.New(logConfig)
|
||||
if err != nil {
|
||||
//nolint:sloglint // we do not have an logger yet
|
||||
slog.Error("failed to create logger",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if *configFile != "" {
|
||||
resolver, err := config.NewResolver(*configFile, logger, *insecure_skip_verify)
|
||||
resolver, err := config.NewResolver(*configFile, logger, *insecureSkipVerify)
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("msg", "could not load config file", "err", err)
|
||||
os.Exit(1)
|
||||
logger.Error("could not load config file",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
err = resolver.Bind(app, os.Args[1:])
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("err", err)
|
||||
os.Exit(1)
|
||||
|
||||
if err = resolver.Bind(app, os.Args[1:]); err != nil {
|
||||
logger.Error("Failed to bind configuration",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
// NOTE: This is temporary fix for issue #1092, calling kingpin.Parse
|
||||
@@ -164,120 +152,115 @@ func main() {
|
||||
*webConfig.WebListenAddresses = (*webConfig.WebListenAddresses)[1:]
|
||||
|
||||
// Parse flags once more to include those discovered in configuration file(s).
|
||||
kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||
if _, err = app.Parse(os.Args[1:]); err != nil {
|
||||
logger.Error("Failed to parse CLI args from YAML file",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
logger, err = winlog.New(winlogConfig)
|
||||
return 1
|
||||
}
|
||||
|
||||
logger, err = log.New(logConfig)
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("err", err)
|
||||
os.Exit(1)
|
||||
//nolint:sloglint // we do not have an logger yet
|
||||
slog.Error("failed to create logger",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debug("Logging has Started")
|
||||
|
||||
if *printCollectors {
|
||||
collectorNames := collector.Available()
|
||||
sort.Strings(collectorNames)
|
||||
printCollectorsToStdout()
|
||||
|
||||
fmt.Printf("Available collectors:\n") //nolint:forbidigo
|
||||
for _, n := range collectorNames {
|
||||
fmt.Printf(" - %s\n", n) //nolint:forbidigo
|
||||
}
|
||||
|
||||
return
|
||||
return 0
|
||||
}
|
||||
|
||||
// Only set process priority if a non-default and valid value has been set
|
||||
if *processPriority != "normal" && priorityStringToInt[*processPriority] != 0 {
|
||||
_ = level.Debug(logger).Log("msg", "setting process priority to "+*processPriority)
|
||||
err = setPriorityWindows(os.Getpid(), priorityStringToInt[*processPriority])
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("msg", "failed to set process priority", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if err = setPriorityWindows(logger, os.Getpid(), *processPriority); err != nil {
|
||||
logger.Error("failed to set process priority",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
if err = wmi.InitWbem(logger); err != nil {
|
||||
_ = level.Error(logger).Log("err", err)
|
||||
os.Exit(1)
|
||||
return 1
|
||||
}
|
||||
|
||||
enabledCollectorList := utils.ExpandEnabledCollectors(*enabledCollectors)
|
||||
collectors.Enable(enabledCollectorList)
|
||||
collectors.SetLogger(logger)
|
||||
if err := collectors.Enable(enabledCollectorList); err != nil {
|
||||
logger.Error(err.Error())
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
// Initialize collectors before loading
|
||||
err = collectors.Build()
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("msg", "Couldn't load collectors", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
err = collectors.SetPerfCounterQuery()
|
||||
if err != nil {
|
||||
_ = level.Error(logger).Log("msg", "Couldn't set performance counter query", "err", err)
|
||||
os.Exit(1)
|
||||
if err = collectors.Build(logger); err != nil {
|
||||
logger.Error("Couldn't load collectors",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if u, err := user.Current(); err != nil {
|
||||
_ = level.Warn(logger).Log("msg", "Unable to determine which user is running this exporter. More info: https://github.com/golang/go/issues/37348")
|
||||
} else {
|
||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Running as %v", u.Username))
|
||||
if err = collectors.SetPerfCounterQuery(logger); err != nil {
|
||||
logger.Error("Couldn't set performance counter query",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
if strings.Contains(u.Username, "ContainerAdministrator") || strings.Contains(u.Username, "ContainerUser") {
|
||||
_ = level.Warn(logger).Log("msg", "Running as a preconfigured Windows Container user. This may mean you do not have Windows HostProcess containers configured correctly and some functionality will not work as expected.")
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Enabled collectors: %v", strings.Join(enabledCollectorList, ", ")))
|
||||
logCurrentUser(logger)
|
||||
|
||||
logger.Info("Enabled collectors: " + strings.Join(enabledCollectorList, ", "))
|
||||
|
||||
if utils.PDHEnabled() {
|
||||
logger.Info("Using performance data helper from PHD.dll for performance counter collection. This is in experimental state.")
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc(*metricsPath, withConcurrencyLimit(*maxRequests, collectors.BuildServeHTTP(*disableExporterMetrics, *timeoutMargin)))
|
||||
mux.HandleFunc("/health", func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, err := fmt.Fprintln(w, `{"status":"ok"}`)
|
||||
if err != nil {
|
||||
_ = level.Debug(logger).Log("msg", "Failed to write to stream", "err", err)
|
||||
}
|
||||
})
|
||||
mux.HandleFunc("/version", func(w http.ResponseWriter, _ *http.Request) {
|
||||
// we can't use "version" directly as it is a package, and not an object that
|
||||
// can be serialized.
|
||||
err := json.NewEncoder(w).Encode(prometheusVersion{
|
||||
Version: version.Version,
|
||||
Revision: version.Revision,
|
||||
Branch: version.Branch,
|
||||
BuildUser: version.BuildUser,
|
||||
BuildDate: version.BuildDate,
|
||||
GoVersion: version.GoVersion,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("error encoding JSON: %s", err), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
mux.Handle("GET /health", httphandler.NewHealthHandler())
|
||||
mux.Handle("GET /version", httphandler.NewVersionHandler())
|
||||
mux.Handle("GET "+*metricsPath, httphandler.New(logger, collectors, &httphandler.Options{
|
||||
DisableExporterMetrics: *disableExporterMetrics,
|
||||
TimeoutMargin: *timeoutMargin,
|
||||
MaxRequests: *maxRequests,
|
||||
}))
|
||||
|
||||
if *debugEnabled {
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
mux.HandleFunc("GET /debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("GET /debug/pprof/cmdline", pprof.Cmdline)
|
||||
mux.HandleFunc("GET /debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("GET /debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("GET /debug/pprof/trace", pprof.Trace)
|
||||
}
|
||||
|
||||
_ = level.Info(logger).Log("msg", "Starting windows_exporter", "version", version.Info())
|
||||
_ = level.Info(logger).Log("msg", "Build context", "build_context", version.BuildContext())
|
||||
_ = level.Debug(logger).Log("msg", "Go MAXPROCS", "procs", runtime.GOMAXPROCS(0))
|
||||
logger.Info("Starting windows_exporter",
|
||||
slog.String("version", version.Version),
|
||||
slog.String("branch", version.Branch),
|
||||
slog.String("revision", version.GetRevision()),
|
||||
slog.String("goversion", version.GoVersion),
|
||||
slog.String("builddate", version.BuildDate),
|
||||
slog.Int("maxprocs", runtime.GOMAXPROCS(0)),
|
||||
)
|
||||
|
||||
server := &http.Server{
|
||||
ReadHeaderTimeout: 5 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Minute,
|
||||
WriteTimeout: 5 * time.Minute,
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
if err := web.ListenAndServe(server, webConfig, logger); err != nil {
|
||||
_ = level.Error(logger).Log("msg", "cannot start windows_exporter", "err", err)
|
||||
os.Exit(1)
|
||||
if err := web.ListenAndServe(server, webConfig, logger); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
errCh <- err
|
||||
}
|
||||
|
||||
errCh <- nil
|
||||
}()
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||
@@ -285,9 +268,17 @@ func main() {
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
_ = level.Info(logger).Log("msg", "Shutting down windows_exporter via kill signal")
|
||||
logger.Info("Shutting down windows_exporter via kill signal")
|
||||
case <-initiate.StopCh:
|
||||
_ = level.Info(logger).Log("msg", "Shutting down windows_exporter via service control")
|
||||
logger.Info("Shutting down windows_exporter via service control")
|
||||
case err := <-errCh:
|
||||
if err != nil {
|
||||
logger.Error("Failed to start windows_exporter",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
@@ -295,24 +286,76 @@ func main() {
|
||||
|
||||
_ = server.Shutdown(ctx)
|
||||
|
||||
_ = level.Info(logger).Log("msg", "windows_exporter has shut down")
|
||||
logger.Info("windows_exporter has shut down")
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func withConcurrencyLimit(n int, next http.HandlerFunc) http.HandlerFunc {
|
||||
if n <= 0 {
|
||||
return next
|
||||
}
|
||||
func printCollectorsToStdout() {
|
||||
collectorNames := collector.Available()
|
||||
sort.Strings(collectorNames)
|
||||
|
||||
sem := make(chan struct{}, n)
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
select {
|
||||
case sem <- struct{}{}:
|
||||
defer func() { <-sem }()
|
||||
default:
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
_, _ = w.Write([]byte("Too many concurrent requests"))
|
||||
return
|
||||
}
|
||||
next(w, r)
|
||||
fmt.Println("Available collectors:") //nolint:forbidigo
|
||||
|
||||
for _, n := range collectorNames {
|
||||
fmt.Printf(" - %s\n", n) //nolint:forbidigo
|
||||
}
|
||||
}
|
||||
|
||||
func logCurrentUser(logger *slog.Logger) {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
logger.Warn("Unable to determine which user is running this exporter. More info: https://github.com/golang/go/issues/37348",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("Running as " + u.Username)
|
||||
|
||||
if strings.Contains(u.Username, "ContainerAdministrator") || strings.Contains(u.Username, "ContainerUser") {
|
||||
logger.Warn("Running as a preconfigured Windows Container user. This may mean you do not have Windows HostProcess containers configured correctly and some functionality will not work as expected.")
|
||||
}
|
||||
}
|
||||
|
||||
// setPriorityWindows sets the priority of the current process to the specified value.
|
||||
func setPriorityWindows(logger *slog.Logger, pid int, priority string) error {
|
||||
// Mapping of priority names to uin32 values required by windows.SetPriorityClass.
|
||||
priorityStringToInt := map[string]uint32{
|
||||
"realtime": windows.REALTIME_PRIORITY_CLASS,
|
||||
"high": windows.HIGH_PRIORITY_CLASS,
|
||||
"abovenormal": windows.ABOVE_NORMAL_PRIORITY_CLASS,
|
||||
"normal": windows.NORMAL_PRIORITY_CLASS,
|
||||
"belownormal": windows.BELOW_NORMAL_PRIORITY_CLASS,
|
||||
"low": windows.IDLE_PRIORITY_CLASS,
|
||||
}
|
||||
|
||||
winPriority, ok := priorityStringToInt[priority]
|
||||
|
||||
// Only set process priority if a non-default and valid value has been set
|
||||
if !ok || winPriority != windows.NORMAL_PRIORITY_CLASS {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Debug("setting process priority to " + priority)
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
||||
handle, err := windows.OpenProcess(
|
||||
windows.STANDARD_RIGHTS_REQUIRED|windows.SYNCHRONIZE|windows.SPECIFIC_RIGHTS_ALL,
|
||||
false, uint32(pid),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open own process: %w", err)
|
||||
}
|
||||
|
||||
if err = windows.SetPriorityClass(handle, winPriority); err != nil {
|
||||
return fmt.Errorf("failed to set priority class: %w", err)
|
||||
}
|
||||
|
||||
if err = windows.CloseHandle(handle); err != nil {
|
||||
return fmt.Errorf("failed to close handle: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
56
go.mod
56
go.mod
@@ -1,53 +1,55 @@
|
||||
module github.com/prometheus-community/windows_exporter
|
||||
|
||||
go 1.22
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.12.5
|
||||
github.com/Microsoft/hcsshim v0.12.9
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1
|
||||
github.com/dimchansky/utfbom v1.1.1
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/go-ole/go-ole v1.3.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.55.0
|
||||
github.com/prometheus/exporter-toolkit v0.11.0
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/prometheus/common v0.60.1
|
||||
github.com/prometheus/exporter-toolkit v0.13.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/yusufpapurcu/wmi v1.2.4
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||
golang.org/x/sys v0.24.0
|
||||
golang.org/x/sys v0.26.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require github.com/pkg/errors v0.9.1
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.2 // indirect
|
||||
github.com/containerd/errdefs v0.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.3 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/mdlayher/socket v0.5.1 // indirect
|
||||
github.com/mdlayher/vsock v1.2.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/oauth2 v0.21.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/grpc v1.62.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/grpc v1.67.1 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
120
go.sum
120
go.sum
@@ -2,23 +2,29 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0=
|
||||
github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8=
|
||||
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
|
||||
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0=
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
|
||||
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
|
||||
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
|
||||
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
|
||||
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
|
||||
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
|
||||
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
|
||||
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso=
|
||||
github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -30,14 +36,11 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
@@ -52,8 +55,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
@@ -63,12 +64,24 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
|
||||
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
|
||||
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
|
||||
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
@@ -77,15 +90,15 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g=
|
||||
github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q=
|
||||
github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
|
||||
github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
|
||||
github.com/prometheus/exporter-toolkit v0.13.1 h1:Evsh0gWQo2bdOHlnz9+0Nm7/OFfIwhE2Ws4A2jIlR04=
|
||||
github.com/prometheus/exporter-toolkit v0.13.1/go.mod h1:ujdv2YIOxtdFxxqtloLpbqmxd5J0Le6IITUvIRSWjj0=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
@@ -95,78 +108,90 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -176,12 +201,11 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -28,7 +28,7 @@ Copy-Item -Force $PathToExecutable Work/windows_exporter.exe
|
||||
Write-Verbose "Creating windows_exporter-${Version}-${Arch}.msi"
|
||||
$wixArch = @{"amd64" = "x64"; "arm64" = "arm64"}[$Arch]
|
||||
|
||||
Invoke-Expression "wix build -arch $wixArch -o .\windows_exporter-$($Version)-$($Arch).msi .\windows_exporter.wxs -d Version=$($MsiVersion) -ext WixToolset.Firewall.wixext -ext WixToolset.Util.wixext"
|
||||
Invoke-Expression "wix build -arch $wixArch -o .\windows_exporter-$($Version)-$($Arch).msi .\files.wxs .\main.wxs -d ProductName=windows_exporter -d Version=$($MsiVersion) -ext WixToolset.Firewall.wixext -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext"
|
||||
|
||||
Write-Verbose "Done!"
|
||||
Pop-Location
|
||||
|
||||
38
installer/files.wxs
Normal file
38
installer/files.wxs
Normal file
@@ -0,0 +1,38 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
|
||||
xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||
<Fragment>
|
||||
<DirectoryRef Id="APPLICATIONFOLDER">
|
||||
<Component Transitive="yes">
|
||||
<File Id="windows_exporter.exe" Name="windows_exporter.exe" Source="Work\windows_exporter.exe" KeyPath="yes" Vital="yes" Checksum="yes"/>
|
||||
<ServiceInstall
|
||||
Id="InstallExporterService"
|
||||
Name="windows_exporter"
|
||||
DisplayName="windows_exporter"
|
||||
Description="Exports Prometheus metrics about the system"
|
||||
ErrorControl="normal"
|
||||
Start="auto"
|
||||
Type="ownProcess"
|
||||
Vital="yes"
|
||||
Arguments="--log.file eventlog [ConfigFileFlag] [CollectorsFlag] [ListenFlag] [MetricsPathFlag] [TextfileDirsFlag] [ExtraFlags]">
|
||||
<util:ServiceConfig
|
||||
ResetPeriodInDays="1"
|
||||
FirstFailureActionType="restart"
|
||||
SecondFailureActionType="restart"
|
||||
ThirdFailureActionType="restart"
|
||||
RestartServiceDelayInSeconds="60"
|
||||
/>
|
||||
<ServiceDependency Id="wmiApSrv" />
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="ServiceStateControl" Name="windows_exporter" Remove="uninstall" Start="install" Stop="both"/>
|
||||
</Component>
|
||||
<Component Id="CreateTextfileDirectory" Directory="textfile_inputs" Guid="d03ef58a-9cbf-4165-ad39-d143e9b27e14">
|
||||
<CreateFolder />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<ComponentGroup Id="CG_Files">
|
||||
<ComponentRef Id="windows_exporter.exe" />
|
||||
<ComponentRef Id="CreateTextfileDirectory" />
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
221
installer/main.wxs
Normal file
221
installer/main.wxs
Normal file
@@ -0,0 +1,221 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<?ifndef Version?>
|
||||
<?error Version must be defined?>
|
||||
<?endif?>
|
||||
<?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
|
||||
<?else ?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
|
||||
<?endif?>
|
||||
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
|
||||
xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall"
|
||||
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
|
||||
<Package UpgradeCode="66a6eb5b-1fc2-4b14-a362-5ceec6413308" Name="$(var.ProductName)" Version="$(var.Version)"
|
||||
Manufacturer="prometheus-community" Language="1033" Scope="perMachine">
|
||||
<SummaryInformation Manufacturer="prometheus-community" Description="$(var.ProductName) $(var.Version) installer" />
|
||||
|
||||
<Upgrade Id="66a6eb5b-1fc2-4b14-a362-5ceec6413308">
|
||||
<UpgradeVersion IncludeMinimum="no"
|
||||
Minimum="$(var.Version)"
|
||||
OnlyDetect="no"
|
||||
Property="NEWERVERSIONDETECTED" />
|
||||
<UpgradeVersion IncludeMaximum="yes"
|
||||
IncludeMinimum="yes"
|
||||
Maximum="$(var.Version)"
|
||||
Minimum="0.0.0.0"
|
||||
Property="OLDERVERSIONBEINGUPGRADED" />
|
||||
</Upgrade>
|
||||
|
||||
<CustomAction Id="set_maintenance" Property="MAINTENANCE" Value="true" />
|
||||
|
||||
<!-- Set to reinstall all features. -->
|
||||
<CustomAction Id="set_reinstall_all_property"
|
||||
Property="REINSTALL"
|
||||
Value="ALL" />
|
||||
<!-- "amus" will force reinstall all files.
|
||||
See https://docs.microsoft.com/en-us/windows/desktop/Msi/reinstallmode -->
|
||||
<CustomAction Id="set_reinstallmode_property"
|
||||
Property="REINSTALLMODE"
|
||||
Value="amus" />
|
||||
<SetProperty
|
||||
Id="CreateConfigFile"
|
||||
Value=""[%ComSpec]" /c TYPE NUL >>"[ConfigFile_NonDefault][ConfigFile_Default]""
|
||||
Before="CreateConfigFile"
|
||||
Sequence="execute"
|
||||
Condition="ConfigFile_NonDefault OR ConfigFile_Default"
|
||||
/>
|
||||
<CustomAction
|
||||
Id="CreateConfigFile"
|
||||
BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)"
|
||||
DllEntry="WixQuietExec"
|
||||
Execute="deferred"
|
||||
Return="check"
|
||||
Impersonate="no"
|
||||
/>
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<!-- Set REINSTALL=all and REINSTALLMODE=amus if the user reruns the
|
||||
MSI, which will force reinstalling all files and services. -->
|
||||
<Custom Action="set_maintenance" Before="set_reinstall_all_property"
|
||||
Condition="Installed AND (NOT REMOVE) AND (NOT UPGRADINGPRODUCTCODE)"/>
|
||||
<Custom Action="set_reinstall_all_property" Before="set_reinstallmode_property" Condition="MAINTENANCE"/>
|
||||
<Custom Action="set_reinstallmode_property" Before="LaunchConditions" Condition="MAINTENANCE"/>
|
||||
<Custom Action="CreateConfigFile" Before="InstallServices" Condition="ConfigFile_NonDefault OR ConfigFile_Default" />
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<Media Id="1" Cabinet="windows_exporter.cab" EmbedCab="yes" />
|
||||
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." AllowSameVersionUpgrades="yes" />
|
||||
|
||||
<Property Id="ENABLED_COLLECTORS" Secure="yes" />
|
||||
<SetProperty Id="CollectorsFlag" After="InstallFiles" Sequence="execute" Value="--collectors.enabled [ENABLED_COLLECTORS]" Condition="ENABLED_COLLECTORS" />
|
||||
|
||||
<Property Id="EXTRA_FLAGS" Secure="yes" />
|
||||
<SetProperty Id="ExtraFlags" After="InstallFiles" Sequence="execute" Value="[EXTRA_FLAGS]" Condition="EXTRA_FLAGS" />
|
||||
|
||||
<Property Id="CONFIG_FILE" Secure="yes" Value="config.yaml" />
|
||||
<SetProperty Id="ConfigFile_NonDefault" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND CONFIG_FILE<>"config.yaml"" />
|
||||
<SetProperty Id="ConfigFile_Default" After="InstallFiles" Sequence="execute" Value="[APPLICATIONFOLDER]config.yaml" Condition="CONFIG_FILE="config.yaml"" />
|
||||
<SetProperty Id="ConfigFileFlag" After="InstallFiles" Sequence="execute" Value="--config.file="[ConfigFile_NonDefault][ConfigFile_Default]"" Condition="ConfigFile_NonDefault OR ConfigFile_Default" />
|
||||
|
||||
<Property Id="LISTEN_PORT" Secure="yes" Value="9182" />
|
||||
<SetProperty Id="ListenFlag" After="InstallFiles" Sequence="execute" Value="--web.listen-address [LISTEN_ADDR]:[LISTEN_PORT]" Condition="LISTEN_ADDR<>"" OR LISTEN_PORT<>9182" />
|
||||
|
||||
<Property Id="METRICS_PATH" Secure="yes" />
|
||||
<SetProperty Id="MetricsPathFlag" After="InstallFiles" Sequence="execute" Value="--telemetry.path [METRICS_PATH]" Condition="METRICS_PATH" />
|
||||
|
||||
<Property Id="REMOTE_ADDR" Secure="yes" />
|
||||
<SetProperty Id="RemoteAddressFlag" After="InstallFiles" Sequence="execute" Value="[REMOTE_ADDR]" Condition="REMOTE_ADDR" />
|
||||
|
||||
<Property Id="TEXTFILE_DIRS" Secure="yes" />
|
||||
<SetProperty Id="TextfileDirsFlag" After="InstallFiles" Sequence="execute" Value="--collector.textfile.directories [TEXTFILE_DIRS]" Condition="TEXTFILE_DIRS" />
|
||||
|
||||
<Property Id="ARPHELPLINK" Value="https://github.com/prometheus-community/windows_exporter/issues" />
|
||||
<Property Id="ARPSIZE" Value="9000" />
|
||||
<Property Id="ARPURLINFOABOUT" Value="https://github.com/prometheus-community/windows_exporter" />
|
||||
<!--<Property Id="ARPNOMODIFY" Value="0" />-->
|
||||
<!--<Property Id="ARPNOREPAIR" Value="1" />-->
|
||||
<Property Id="START_MENU_FOLDER" Value="0" />
|
||||
<Property Id="NOSTART" Value="0" />
|
||||
|
||||
<Feature
|
||||
Id="DefaultFeature"
|
||||
Level="1"
|
||||
Title="$(var.ProductName) $(var.Version)"
|
||||
Description="The binary and configuration files for $(var.ProductName)"
|
||||
Display="expand"
|
||||
ConfigurableDirectory="APPLICATIONFOLDER"
|
||||
AllowAdvertise="no"
|
||||
InstallDefault="local"
|
||||
AllowAbsent="no"
|
||||
>
|
||||
<ComponentGroupRef Id="CG_Files" />
|
||||
|
||||
<Feature
|
||||
Id="FirewallException"
|
||||
Level="2"
|
||||
Title="Firewall Exception"
|
||||
Description="Allow $(var.ProductName) to listen on a port"
|
||||
Display="expand"
|
||||
AllowAdvertise="no"
|
||||
AllowAbsent="yes">
|
||||
<ComponentGroupRef Id="CG_FirewallException" />
|
||||
</Feature>
|
||||
</Feature>
|
||||
|
||||
<UI Id="FeatureTree">
|
||||
<ui:WixUI Id="WixUI_FeatureTree" />
|
||||
<UIRef Id="WixUI_ErrorProgressText" />
|
||||
<Dialog Id="CustomPropertiesDlg" Width="370" Height="270" Title="windows_exporter configuration">
|
||||
<Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.CustomizeDlgBannerBitmap)" />
|
||||
<!--<Control Id="Text" Type="Text" X="25" Y="55" Width="320" Height="20" Text="Text" />-->
|
||||
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
|
||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
||||
<Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="This pages contains configuration related to windows_exporter" />
|
||||
<Control Id="Title" Type="Text" X="15" Y="6" Width="210" Height="15" Transparent="yes" NoPrefix="yes" Text="{\WixUI_Font_Title}windows_exporter configuration" />
|
||||
|
||||
<!-- Edit box for property input -->
|
||||
<!-- cpu,cs,logical_disk,physical_disk,net,os,service,system -->
|
||||
<Control Id="PropertyEdit_ENABLED_COLLECTORS_Title1" Type="Text" X="25" Y="55" Width="300" Height="15" Transparent="yes" NoPrefix="yes" Text="Comma-separated list of collectors to use. Use '[\[]defaults[\]]' as a placeholder for all" />
|
||||
<Control Id="PropertyEdit_ENABLED_COLLECTORS_Title2" Type="Text" X="25" Y="65" Width="300" Height="15" Transparent="yes" NoPrefix="yes" Text="the collectors enabled by default. If value is empty, the exporter default will be used." />
|
||||
<Control Id="PropertyEdit_ENABLED_COLLECTORS" Type="Edit" X="24" Y="77" Width="300" Height="18" Property="ENABLED_COLLECTORS" Text="[ENABLED_COLLECTORS]" Indirect="no" />
|
||||
|
||||
<Control Id="PropertyEdit_EXTRA_FLAGS_Title" Type="Text" X="25" Y="100" Width="300" Height="15" Transparent="yes" NoPrefix="yes" Text="Additional command line flags" />
|
||||
<Control Id="PropertyEdit_EXTRA_FLAGS" Type="Edit" X="24" Y="112" Width="300" Height="18" Property="EXTRA_FLAGS" Text="[EXTRA_FLAGS]" Indirect="no" />
|
||||
|
||||
<Control Id="PropertyEdit_LISTEN_PORT_Title" Type="Text" X="25" Y="135" Width="300" Height="15" Transparent="yes" NoPrefix="yes" Text="Port to listen" />
|
||||
<Control Id="PropertyEdit_LISTEN_PORT" Type="Edit" X="24" Y="147" Width="300" Height="18" Property="LISTEN_PORT" Text="[LISTEN_PORT]" Indirect="no" />
|
||||
|
||||
<Control Id="PropertyEdit_CONFIG_FILE_Title1" Type="Text" X="25" Y="170" Width="300" Height="15" Transparent="yes" NoPrefix="yes" Text="Path to config file. If empty, no config will be used. If set to 'config.yaml', " />
|
||||
<Control Id="PropertyEdit_CONFIG_FILE_Title2" Type="Text" X="25" Y="180" Width="300" Height="15" Transparent="yes" NoPrefix="yes" Text="then the config.yaml at the install path will be used." />
|
||||
<Control Id="PropertyEdit_CONFIG_FILE" Type="Edit" X="24" Y="192" Width="300" Height="18" Property="CONFIG_FILE" Text="[CONFIG_FILE]" Indirect="no" />
|
||||
|
||||
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
|
||||
<Publish Event="NewDialog" Value="VerifyReadyDlg" />
|
||||
</Control>
|
||||
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)">
|
||||
<Publish Event="NewDialog" Value="CustomizeDlg" />
|
||||
</Control>
|
||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
|
||||
<Publish Event="SpawnDialog" Value="CancelDlg" />
|
||||
</Control>
|
||||
</Dialog>
|
||||
|
||||
<!-- skip the license agreement dialog; higher Order takes priority (weird) -->
|
||||
|
||||
<Publish
|
||||
Condition="NOT Installed"
|
||||
Dialog="WelcomeDlg"
|
||||
Control="Next"
|
||||
Event="NewDialog"
|
||||
Value="CustomizeDlg"
|
||||
Order="10"/>
|
||||
<Publish
|
||||
Condition="NOT Installed"
|
||||
Dialog="CustomizeDlg"
|
||||
Control="Back"
|
||||
Event="NewDialog"
|
||||
Value="WelcomeDlg"
|
||||
Order="10"/>
|
||||
<Publish
|
||||
Dialog="CustomizeDlg"
|
||||
Control="Next"
|
||||
Event="NewDialog"
|
||||
Value="CustomPropertiesDlg"
|
||||
Order="10"/>
|
||||
<Publish
|
||||
Dialog="VerifyReadyDlg"
|
||||
Control="Back"
|
||||
Event="NewDialog"
|
||||
Value="CustomPropertiesDlg"
|
||||
Order="10"/>
|
||||
|
||||
|
||||
<!--CustomPropertyDlg-->
|
||||
</UI>
|
||||
|
||||
<!-- InstallLocation key -->
|
||||
<CustomAction Id="SetInstallLocation" Property="ARPINSTALLLOCATION" Value="[APPLICATIONFOLDER]" />
|
||||
|
||||
<StandardDirectory Id="ProgramFiles64Folder">
|
||||
<Directory Id="APPLICATIONFOLDER" Name="windows_exporter">
|
||||
<Directory Id="textfile_inputs" Name="textfile_inputs" />
|
||||
</Directory>
|
||||
</StandardDirectory>
|
||||
|
||||
<ComponentGroup Id="CG_FirewallException">
|
||||
<Component Directory="APPLICATIONFOLDER" Id="C_FirewallException" Guid="9f522655-ac0e-42d2-a512-a7b19ebec7f7">
|
||||
<fw:FirewallException
|
||||
Id="MetricsEndpoint"
|
||||
Name="$(var.ProductName)"
|
||||
Description="$(var.ProductName) HTTP endpoint"
|
||||
Program="[#windows_exporter.exe]"
|
||||
Port="[LISTEN_PORT]"
|
||||
Protocol="tcp">
|
||||
<fw:RemoteAddress Value="[REMOTE_ADDR]" />
|
||||
</fw:FirewallException>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Package>
|
||||
</Wix>
|
||||
@@ -1,110 +0,0 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||
<?if $(sys.BUILDARCH)=x64 ?>
|
||||
<?define PlatformProgramFiles = "ProgramFiles64Folder" ?>
|
||||
<?else?>
|
||||
<?define PlatformProgramFiles = "ProgramFilesFolder" ?>
|
||||
<?endif?>
|
||||
|
||||
<Package UpgradeCode="66a6eb5b-1fc2-4b14-a362-5ceec6413308" Name="windows_exporter" Version="$(var.Version)" Manufacturer="prometheus-community" Language="1033" Codepage="1252">
|
||||
<SummaryInformation Manufacturer="prometheus-community" Description="windows_exporter $(var.Version) installer" />
|
||||
|
||||
<Media Id="1" Cabinet="windows_exporter.cab" EmbedCab="yes" />
|
||||
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." />
|
||||
|
||||
<Property Id="ENABLED_COLLECTORS" Secure="yes" />
|
||||
<SetProperty Id="CollectorsFlag" After="InstallFiles" Sequence="execute" Value="--collectors.enabled [ENABLED_COLLECTORS]" Condition="ENABLED_COLLECTORS" />
|
||||
|
||||
<Property Id="EXTRA_FLAGS" Secure="yes" />
|
||||
<SetProperty Id="ExtraFlags" After="InstallFiles" Sequence="execute" Value="[EXTRA_FLAGS]" Condition="EXTRA_FLAGS" />
|
||||
|
||||
<Property Id="ADD_FIREWALL_EXCEPTION" Secure="yes" />
|
||||
|
||||
<Property Id="ENABLE_V1_PERFORMANCE_COUNTERS" Secure="yes" />
|
||||
|
||||
<Property Id="LISTEN_PORT" Secure="yes" Value="9182" />
|
||||
<SetProperty Id="ListenFlag" After="InstallFiles" Sequence="execute" Value="--web.listen-address [LISTEN_ADDR]:[LISTEN_PORT]" Condition="LISTEN_ADDR<>"" OR LISTEN_PORT<>9182" />
|
||||
|
||||
<Property Id="METRICS_PATH" Secure="yes" />
|
||||
<SetProperty Id="MetricsPathFlag" After="InstallFiles" Sequence="execute" Value="--telemetry.path [METRICS_PATH]" Condition="METRICS_PATH" />
|
||||
|
||||
<Property Id="REMOTE_ADDR" Secure="yes" />
|
||||
<SetProperty Id="RemoteAddressFlag" After="InstallFiles" Sequence="execute" Value="[REMOTE_ADDR]" Condition="REMOTE_ADDR" />
|
||||
|
||||
<!-- https://github.com/prometheus-community/windows_exporter/issues/1318 -->
|
||||
<!-- https://wixtoolset.org/docs/tools/wixext/quietexec/ -->
|
||||
<SetProperty
|
||||
Id="WixQuietExecCmdLine"
|
||||
Value=""[%ComSpec]" /c reg delete HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\windows_exporter /f"
|
||||
Before="RemoveEventSource"
|
||||
Sequence="execute"
|
||||
/>
|
||||
<CustomAction
|
||||
Id="RemoveEventSource"
|
||||
BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)"
|
||||
DllEntry="WixSilentExec"
|
||||
Execute="deferred"
|
||||
Impersonate="no"
|
||||
Return="ignore"
|
||||
/>
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="RemoveEventSource" After="InstallInitialize" />
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<SetProperty
|
||||
Id="EnableV1PerformanceCounters"
|
||||
Value=""[%ComSpec]" /c lodctr.exe /E:Lsa & lodctr.exe /E:PerfProc & lodctr.exe /R"
|
||||
Before="EnableV1PerformanceCounters"
|
||||
Sequence="execute"
|
||||
/>
|
||||
<CustomAction
|
||||
Id="EnableV1PerformanceCounters"
|
||||
BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)"
|
||||
DllEntry="WixSilentExec"
|
||||
Execute="deferred"
|
||||
Impersonate="no"
|
||||
Return="check"
|
||||
/>
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="EnableV1PerformanceCounters" Before="InstallFinalize" Condition="ENABLE_V1_PERFORMANCE_COUNTERS="yes""/>
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<Property Id="TEXTFILE_DIRS" Secure="yes" />
|
||||
<SetProperty Id="TextfileDirsFlag" After="InstallFiles" Sequence="execute" Value="--collector.textfile.directories [TEXTFILE_DIRS]" Condition="TEXTFILE_DIRS" />
|
||||
|
||||
<ComponentGroup Id="Files">
|
||||
<Component Directory="APPLICATIONROOTDIRECTORY">
|
||||
<File Id="windows_exporter.exe" Name="windows_exporter.exe" Source="Work\windows_exporter.exe" KeyPath="yes" />
|
||||
<ServiceInstall Id="InstallExporterService" Name="windows_exporter" DisplayName="windows_exporter" Description="Exports Prometheus metrics about the system" ErrorControl="normal" Start="auto" Type="ownProcess" Arguments="--log.file eventlog [CollectorsFlag] [ListenFlag] [MetricsPathFlag] [TextfileDirsFlag] [ExtraFlags]">
|
||||
<util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" RestartServiceDelayInSeconds="60" />
|
||||
<ServiceDependency Id="wmiApSrv" />
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="ServiceStateControl" Name="windows_exporter" Remove="uninstall" Start="install" Stop="both" />
|
||||
</Component>
|
||||
<Component Id="CreateTextfileDirectory" Directory="textfile_inputs" Guid="d03ef58a-9cbf-4165-ad39-d143e9b27e14">
|
||||
<CreateFolder />
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="CG_FirewallException">
|
||||
<Component Condition="ADD_FIREWALL_EXCEPTION="yes"" Directory="APPLICATIONROOTDIRECTORY" Id="C_FirewallException" Guid="9f522655-ac0e-42d2-a512-a7b19ebec7f7">
|
||||
<fw:FirewallException Id="MetricsEndpoint" Name="windows_exporter (HTTP [LISTEN_PORT])" Description="windows_exporter HTTP endpoint" Port="[LISTEN_PORT]" Protocol="tcp" IgnoreFailure="yes">
|
||||
<fw:RemoteAddress Value="[REMOTE_ADDR]" />
|
||||
</fw:FirewallException>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
|
||||
<Feature Id="DefaultFeature" Level="1">
|
||||
<ComponentGroupRef Id="Files" />
|
||||
</Feature>
|
||||
|
||||
<Feature Id="FirewallException" Level="1">
|
||||
<ComponentGroupRef Id="CG_FirewallException" />
|
||||
</Feature>
|
||||
|
||||
<StandardDirectory Id="ProgramFiles64Folder">
|
||||
<Directory Id="APPLICATIONROOTDIRECTORY" Name="windows_exporter">
|
||||
<Directory Id="textfile_inputs" Name="textfile_inputs" />
|
||||
</Directory>
|
||||
</StandardDirectory>
|
||||
</Package>
|
||||
</Wix>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,8 @@ package ad_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/ad"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/ad"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
359
internal/collector/ad/const.go
Normal file
359
internal/collector/ad/const.go
Normal file
@@ -0,0 +1,359 @@
|
||||
package ad
|
||||
|
||||
const (
|
||||
abANRPerSec = "AB ANR/sec"
|
||||
abBrowsesPerSec = "AB Browses/sec"
|
||||
abClientSessions = "AB Client Sessions"
|
||||
abMatchesPerSec = "AB Matches/sec"
|
||||
abPropertyReadsPerSec = "AB Property Reads/sec"
|
||||
abProxyLookupsPerSec = "AB Proxy Lookups/sec"
|
||||
abSearchesPerSec = "AB Searches/sec"
|
||||
approximateHighestDNT = "Approximate highest DNT"
|
||||
atqEstimatedQueueDelay = "ATQ Estimated Queue Delay"
|
||||
atqOutstandingQueuedRequests = "ATQ Outstanding Queued Requests"
|
||||
_ = "ATQ Queue Latency"
|
||||
atqRequestLatency = "ATQ Request Latency"
|
||||
atqThreadsLDAP = "ATQ Threads LDAP"
|
||||
atqThreadsOther = "ATQ Threads Other"
|
||||
atqThreadsTotal = "ATQ Threads Total"
|
||||
baseSearchesPerSec = "Base searches/sec"
|
||||
databaseAddsPerSec = "Database adds/sec"
|
||||
databaseDeletesPerSec = "Database deletes/sec"
|
||||
databaseModifiesPerSec = "Database modifys/sec"
|
||||
databaseRecyclesPerSec = "Database recycles/sec"
|
||||
digestBindsPerSec = "Digest Binds/sec"
|
||||
_ = "DirSync session throttling rate"
|
||||
_ = "DirSync sessions in progress"
|
||||
draHighestUSNCommittedHighPart = "DRA Highest USN Committed (High part)"
|
||||
draHighestUSNCommittedLowPart = "DRA Highest USN Committed (Low part)"
|
||||
draHighestUSNIssuedHighPart = "DRA Highest USN Issued (High part)"
|
||||
draHighestUSNIssuedLowPart = "DRA Highest USN Issued (Low part)"
|
||||
draInboundBytesCompressedBetweenSitesAfterCompressionSinceBoot = "DRA Inbound Bytes Compressed (Between Sites, After Compression) Since Boot"
|
||||
draInboundBytesCompressedBetweenSitesAfterCompressionPerSec = "DRA Inbound Bytes Compressed (Between Sites, After Compression)/sec"
|
||||
draInboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot = "DRA Inbound Bytes Compressed (Between Sites, Before Compression) Since Boot"
|
||||
draInboundBytesCompressedBetweenSitesBeforeCompressionPerSec = "DRA Inbound Bytes Compressed (Between Sites, Before Compression)/sec"
|
||||
draInboundBytesNotCompressedWithinSiteSinceBoot = "DRA Inbound Bytes Not Compressed (Within Site) Since Boot"
|
||||
draInboundBytesNotCompressedWithinSitePerSec = "DRA Inbound Bytes Not Compressed (Within Site)/sec"
|
||||
draInboundBytesTotalSinceBoot = "DRA Inbound Bytes Total Since Boot"
|
||||
draInboundBytesTotalPerSec = "DRA Inbound Bytes Total/sec"
|
||||
draInboundFullSyncObjectsRemaining = "DRA Inbound Full Sync Objects Remaining"
|
||||
draInboundLinkValueUpdatesRemainingInPacket = "DRA Inbound Link Value Updates Remaining in Packet"
|
||||
_ = "DRA Inbound Link Values/sec"
|
||||
draInboundObjectUpdatesRemainingInPacket = "DRA Inbound Object Updates Remaining in Packet"
|
||||
draInboundObjectsAppliedPerSec = "DRA Inbound Objects Applied/sec"
|
||||
draInboundObjectsFilteredPerSec = "DRA Inbound Objects Filtered/sec"
|
||||
draInboundObjectsPerSec = "DRA Inbound Objects/sec"
|
||||
draInboundPropertiesAppliedPerSec = "DRA Inbound Properties Applied/sec"
|
||||
draInboundPropertiesFilteredPerSec = "DRA Inbound Properties Filtered/sec"
|
||||
draInboundPropertiesTotalPerSec = "DRA Inbound Properties Total/sec"
|
||||
_ = "DRA Inbound Sync Link Deletion/sec"
|
||||
draInboundTotalUpdatesRemainingInPacket = "DRA Inbound Total Updates Remaining in Packet"
|
||||
draInboundValuesDNsOnlyPerSec = "DRA Inbound Values (DNs only)/sec"
|
||||
draInboundValuesTotalPerSec = "DRA Inbound Values Total/sec"
|
||||
_ = "DRA number of NC replication calls since boot"
|
||||
_ = "DRA number of successful NC replication calls since boot"
|
||||
draOutboundBytesCompressedBetweenSitesAfterCompressionSinceBoot = "DRA Outbound Bytes Compressed (Between Sites, After Compression) Since Boot"
|
||||
draOutboundBytesCompressedBetweenSitesAfterCompressionPerSec = "DRA Outbound Bytes Compressed (Between Sites, After Compression)/sec"
|
||||
draOutboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot = "DRA Outbound Bytes Compressed (Between Sites, Before Compression) Since Boot"
|
||||
draOutboundBytesCompressedBetweenSitesBeforeCompressionPerSec = "DRA Outbound Bytes Compressed (Between Sites, Before Compression)/sec"
|
||||
draOutboundBytesNotCompressedWithinSiteSinceBoot = "DRA Outbound Bytes Not Compressed (Within Site) Since Boot"
|
||||
draOutboundBytesNotCompressedWithinSitePerSec = "DRA Outbound Bytes Not Compressed (Within Site)/sec"
|
||||
draOutboundBytesTotalSinceBoot = "DRA Outbound Bytes Total Since Boot"
|
||||
draOutboundBytesTotalPerSec = "DRA Outbound Bytes Total/sec"
|
||||
draOutboundObjectsFilteredPerSec = "DRA Outbound Objects Filtered/sec"
|
||||
draOutboundObjectsPerSec = "DRA Outbound Objects/sec"
|
||||
draOutboundPropertiesPerSec = "DRA Outbound Properties/sec"
|
||||
draOutboundValuesDNsOnlyPerSec = "DRA Outbound Values (DNs only)/sec"
|
||||
draOutboundValuesTotalPerSec = "DRA Outbound Values Total/sec"
|
||||
draPendingReplicationOperations = "DRA Pending Replication Operations"
|
||||
draPendingReplicationSynchronizations = "DRA Pending Replication Synchronizations"
|
||||
draSyncFailuresOnSchemaMismatch = "DRA Sync Failures on Schema Mismatch"
|
||||
draSyncRequestsMade = "DRA Sync Requests Made"
|
||||
draSyncRequestsSuccessful = "DRA Sync Requests Successful"
|
||||
draThreadsGettingNCChanges = "DRA Threads Getting NC Changes"
|
||||
draThreadsGettingNCChangesHoldingSemaphore = "DRA Threads Getting NC Changes Holding Semaphore"
|
||||
_ = "DRA total number of Busy failures since boot"
|
||||
_ = "DRA total number of MissingParent failures since boot"
|
||||
_ = "DRA total number of NotEnoughAttrs/MissingObject failures since boot"
|
||||
_ = "DRA total number of Preempted failures since boot"
|
||||
_ = "DRA total time of applying replication package since boot"
|
||||
_ = "DRA total time of NC replication calls since boot"
|
||||
_ = "DRA total time of successful NC replication calls since boot"
|
||||
_ = "DRA total time of successfully applying replication package since boot"
|
||||
_ = "DRA total time on waiting async replication packages since boot"
|
||||
_ = "DRA total time on waiting sync replication packages since boot"
|
||||
dsPercentReadsFromDRA = "DS % Reads from DRA"
|
||||
dsPercentReadsFromKCC = "DS % Reads from KCC"
|
||||
dsPercentReadsFromLSA = "DS % Reads from LSA"
|
||||
dsPercentReadsFromNSPI = "DS % Reads from NSPI"
|
||||
dsPercentReadsFromNTDSAPI = "DS % Reads from NTDSAPI"
|
||||
dsPercentReadsFromSAM = "DS % Reads from SAM"
|
||||
dsPercentReadsOther = "DS % Reads Other"
|
||||
dsPercentSearchesFromDRA = "DS % Searches from DRA"
|
||||
dsPercentSearchesFromKCC = "DS % Searches from KCC"
|
||||
dsPercentSearchesFromLDAP = "DS % Searches from LDAP"
|
||||
dsPercentSearchesFromLSA = "DS % Searches from LSA"
|
||||
dsPercentSearchesFromNSPI = "DS % Searches from NSPI"
|
||||
dsPercentSearchesFromNTDSAPI = "DS % Searches from NTDSAPI"
|
||||
dsPercentSearchesFromSAM = "DS % Searches from SAM"
|
||||
dsPercentSearchesOther = "DS % Searches Other"
|
||||
dsPercentWritesFromDRA = "DS % Writes from DRA"
|
||||
dsPercentWritesFromKCC = "DS % Writes from KCC"
|
||||
dsPercentWritesFromLDAP = "DS % Writes from LDAP"
|
||||
dsPercentWritesFromLSA = "DS % Writes from LSA"
|
||||
dsPercentWritesFromNSPI = "DS % Writes from NSPI"
|
||||
dsPercentWritesFromNTDSAPI = "DS % Writes from NTDSAPI"
|
||||
dsPercentWritesFromSAM = "DS % Writes from SAM"
|
||||
dsPercentWritesOther = "DS % Writes Other"
|
||||
dsClientBindsPerSec = "DS Client Binds/sec"
|
||||
dsClientNameTranslationsPerSec = "DS Client Name Translations/sec"
|
||||
dsDirectoryReadsPerSec = "DS Directory Reads/sec"
|
||||
dsDirectorySearchesPerSec = "DS Directory Searches/sec"
|
||||
dsDirectoryWritesPerSec = "DS Directory Writes/sec"
|
||||
dsMonitorListSize = "DS Monitor List Size"
|
||||
dsNameCacheHitRate = "DS Name Cache hit rate"
|
||||
dsNotifyQueueSize = "DS Notify Queue Size"
|
||||
dsSearchSubOperationsPerSec = "DS Search sub-operations/sec"
|
||||
dsSecurityDescriptorPropagationsEvents = "DS Security Descriptor Propagations Events"
|
||||
dsSecurityDescriptorPropagatorAverageExclusionTime = "DS Security Descriptor Propagator Average Exclusion Time"
|
||||
dsSecurityDescriptorPropagatorRuntimeQueue = "DS Security Descriptor Propagator Runtime Queue"
|
||||
dsSecurityDescriptorSubOperationsPerSec = "DS Security Descriptor sub-operations/sec"
|
||||
dsServerBindsPerSec = "DS Server Binds/sec"
|
||||
dsServerNameTranslationsPerSec = "DS Server Name Translations/sec"
|
||||
dsThreadsInUse = "DS Threads in Use"
|
||||
_ = "Error eventlogs since boot"
|
||||
_ = "Error events since boot"
|
||||
externalBindsPerSec = "External Binds/sec"
|
||||
fastBindsPerSec = "Fast Binds/sec"
|
||||
_ = "Fatal events since boot"
|
||||
_ = "Info eventlogs since boot"
|
||||
ldapActiveThreads = "LDAP Active Threads"
|
||||
_ = "LDAP Add Operations"
|
||||
_ = "LDAP Add Operations/sec"
|
||||
_ = "LDAP batch slots available"
|
||||
ldapBindTime = "LDAP Bind Time"
|
||||
_ = "LDAP busy retries"
|
||||
_ = "LDAP busy retries/sec"
|
||||
ldapClientSessions = "LDAP Client Sessions"
|
||||
ldapClosedConnectionsPerSec = "LDAP Closed Connections/sec"
|
||||
_ = "LDAP Delete Operations"
|
||||
_ = "LDAP Delete Operations/sec"
|
||||
_ = "LDAP Modify DN Operations"
|
||||
_ = "LDAP Modify DN Operations/sec"
|
||||
_ = "LDAP Modify Operations"
|
||||
_ = "LDAP Modify Operations/sec"
|
||||
ldapNewConnectionsPerSec = "LDAP New Connections/sec"
|
||||
ldapNewSSLConnectionsPerSec = "LDAP New SSL Connections/sec"
|
||||
_ = "LDAP Outbound Bytes"
|
||||
_ = "LDAP Outbound Bytes/sec"
|
||||
_ = "LDAP Page Search Cache entries count"
|
||||
_ = "LDAP Page Search Cache size"
|
||||
ldapSearchesPerSec = "LDAP Searches/sec"
|
||||
ldapSuccessfulBindsPerSec = "LDAP Successful Binds/sec"
|
||||
_ = "LDAP Threads Sleeping on BUSY"
|
||||
ldapUDPOperationsPerSec = "LDAP UDP operations/sec"
|
||||
ldapWritesPerSec = "LDAP Writes/sec"
|
||||
linkValuesCleanedPerSec = "Link Values Cleaned/sec"
|
||||
_ = "Links added"
|
||||
_ = "Links added/sec"
|
||||
_ = "Links visited"
|
||||
_ = "Links visited/sec"
|
||||
_ = "Logical link deletes"
|
||||
_ = "Logical link deletes/sec"
|
||||
negotiatedBindsPerSec = "Negotiated Binds/sec"
|
||||
ntlmBindsPerSec = "NTLM Binds/sec"
|
||||
_ = "Objects returned"
|
||||
_ = "Objects returned/sec"
|
||||
_ = "Objects visited"
|
||||
_ = "Objects visited/sec"
|
||||
oneLevelSearchesPerSec = "Onelevel searches/sec"
|
||||
_ = "PDC failed password update notifications"
|
||||
_ = "PDC password update notifications/sec"
|
||||
_ = "PDC successful password update notifications"
|
||||
phantomsCleanedPerSec = "Phantoms Cleaned/sec"
|
||||
phantomsVisitedPerSec = "Phantoms Visited/sec"
|
||||
_ = "Physical link deletes"
|
||||
_ = "Physical link deletes/sec"
|
||||
_ = "Replicate Single Object operations"
|
||||
_ = "Replicate Single Object operations/sec"
|
||||
_ = "RID Pool invalidations since boot"
|
||||
_ = "RID Pool request failures since boot"
|
||||
_ = "RID Pool request successes since boot"
|
||||
samAccountGroupEvaluationLatency = "SAM Account Group Evaluation Latency"
|
||||
samDisplayInformationQueriesPerSec = "SAM Display Information Queries/sec"
|
||||
samDomainLocalGroupMembershipEvaluationsPerSec = "SAM Domain Local Group Membership Evaluations/sec"
|
||||
samEnumerationsPerSec = "SAM Enumerations/sec"
|
||||
samGCEvaluationsPerSec = "SAM GC Evaluations/sec"
|
||||
samGlobalGroupMembershipEvaluationsPerSec = "SAM Global Group Membership Evaluations/sec"
|
||||
samMachineCreationAttemptsPerSec = "SAM Machine Creation Attempts/sec"
|
||||
samMembershipChangesPerSec = "SAM Membership Changes/sec"
|
||||
samNonTransitiveMembershipEvaluationsPerSec = "SAM Non-Transitive Membership Evaluations/sec"
|
||||
samPasswordChangesPerSec = "SAM Password Changes/sec"
|
||||
samResourceGroupEvaluationLatency = "SAM Resource Group Evaluation Latency"
|
||||
samSuccessfulComputerCreationsPerSecIncludesAllRequests = "SAM Successful Computer Creations/sec: Includes all requests"
|
||||
samSuccessfulUserCreationsPerSec = "SAM Successful User Creations/sec"
|
||||
samTransitiveMembershipEvaluationsPerSec = "SAM Transitive Membership Evaluations/sec"
|
||||
samUniversalGroupMembershipEvaluationsPerSec = "SAM Universal Group Membership Evaluations/sec"
|
||||
samUserCreationAttemptsPerSec = "SAM User Creation Attempts/sec"
|
||||
simpleBindsPerSec = "Simple Binds/sec"
|
||||
subtreeSearchesPerSec = "Subtree searches/sec"
|
||||
tombstonesGarbageCollectedPerSec = "Tombstones Garbage Collected/sec"
|
||||
tombstonesVisitedPerSec = "Tombstones Visited/sec"
|
||||
transitiveOperationsMillisecondsRun = "Transitive operations milliseconds run"
|
||||
transitiveOperationsPerSec = "Transitive operations/sec"
|
||||
transitiveSubOperationsPerSec = "Transitive suboperations/sec"
|
||||
_ = "Warning eventlogs since boot"
|
||||
_ = "Warning events since boot"
|
||||
)
|
||||
|
||||
// Win32_PerfRawData_DirectoryServices_DirectoryServices docs:
|
||||
// - https://msdn.microsoft.com/en-us/library/ms803980.aspx
|
||||
type Win32_PerfRawData_DirectoryServices_DirectoryServices struct {
|
||||
Name string
|
||||
|
||||
ABANRPersec uint32
|
||||
ABBrowsesPersec uint32
|
||||
ABClientSessions uint32
|
||||
ABMatchesPersec uint32
|
||||
ABPropertyReadsPersec uint32
|
||||
ABProxyLookupsPersec uint32
|
||||
ABSearchesPersec uint32
|
||||
ApproximatehighestDNT uint32
|
||||
ATQEstimatedQueueDelay uint32
|
||||
ATQOutstandingQueuedRequests uint32
|
||||
ATQRequestLatency uint32
|
||||
ATQThreadsLDAP uint32
|
||||
ATQThreadsOther uint32
|
||||
ATQThreadsTotal uint32
|
||||
BasesearchesPersec uint32
|
||||
DatabaseaddsPersec uint32
|
||||
DatabasedeletesPersec uint32
|
||||
DatabasemodifysPersec uint32
|
||||
DatabaserecyclesPersec uint32
|
||||
DigestBindsPersec uint32
|
||||
DRAHighestUSNCommittedHighpart uint64
|
||||
DRAHighestUSNCommittedLowpart uint64
|
||||
DRAHighestUSNIssuedHighpart uint64
|
||||
DRAHighestUSNIssuedLowpart uint64
|
||||
DRAInboundBytesCompressedBetweenSitesAfterCompressionPersec uint32
|
||||
DRAInboundBytesCompressedBetweenSitesAfterCompressionSinceBoot uint32
|
||||
DRAInboundBytesCompressedBetweenSitesBeforeCompressionPersec uint32
|
||||
DRAInboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot uint32
|
||||
DRAInboundBytesNotCompressedWithinSitePersec uint32
|
||||
DRAInboundBytesNotCompressedWithinSiteSinceBoot uint32
|
||||
DRAInboundBytesTotalPersec uint32
|
||||
DRAInboundBytesTotalSinceBoot uint32
|
||||
DRAInboundFullSyncObjectsRemaining uint32
|
||||
DRAInboundLinkValueUpdatesRemaininginPacket uint32
|
||||
DRAInboundObjectsAppliedPersec uint32
|
||||
DRAInboundObjectsFilteredPersec uint32
|
||||
DRAInboundObjectsPersec uint32
|
||||
DRAInboundObjectUpdatesRemaininginPacket uint32
|
||||
DRAInboundPropertiesAppliedPersec uint32
|
||||
DRAInboundPropertiesFilteredPersec uint32
|
||||
DRAInboundPropertiesTotalPersec uint32
|
||||
DRAInboundTotalUpdatesRemaininginPacket uint32
|
||||
DRAInboundValuesDNsonlyPersec uint32
|
||||
DRAInboundValuesTotalPersec uint32
|
||||
DRAOutboundBytesCompressedBetweenSitesAfterCompressionPersec uint32
|
||||
DRAOutboundBytesCompressedBetweenSitesAfterCompressionSinceBoot uint32
|
||||
DRAOutboundBytesCompressedBetweenSitesBeforeCompressionPersec uint32
|
||||
DRAOutboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot uint32
|
||||
DRAOutboundBytesNotCompressedWithinSitePersec uint32
|
||||
DRAOutboundBytesNotCompressedWithinSiteSinceBoot uint32
|
||||
DRAOutboundBytesTotalPersec uint32
|
||||
DRAOutboundBytesTotalSinceBoot uint32
|
||||
DRAOutboundObjectsFilteredPersec uint32
|
||||
DRAOutboundObjectsPersec uint32
|
||||
DRAOutboundPropertiesPersec uint32
|
||||
DRAOutboundValuesDNsonlyPersec uint32
|
||||
DRAOutboundValuesTotalPersec uint32
|
||||
DRAPendingReplicationOperations uint32
|
||||
DRAPendingReplicationSynchronizations uint32
|
||||
DRASyncFailuresonSchemaMismatch uint32
|
||||
DRASyncRequestsMade uint32
|
||||
DRASyncRequestsSuccessful uint32
|
||||
DRAThreadsGettingNCChanges uint32
|
||||
DRAThreadsGettingNCChangesHoldingSemaphore uint32
|
||||
DSClientBindsPersec uint32
|
||||
DSClientNameTranslationsPersec uint32
|
||||
DSDirectoryReadsPersec uint32
|
||||
DSDirectorySearchesPersec uint32
|
||||
DSDirectoryWritesPersec uint32
|
||||
DSMonitorListSize uint32
|
||||
DSNameCachehitrate uint32
|
||||
DSNameCachehitrate_Base uint32
|
||||
DSNotifyQueueSize uint32
|
||||
DSPercentReadsfromDRA uint32
|
||||
DSPercentReadsfromKCC uint32
|
||||
DSPercentReadsfromLSA uint32
|
||||
DSPercentReadsfromNSPI uint32
|
||||
DSPercentReadsfromNTDSAPI uint32
|
||||
DSPercentReadsfromSAM uint32
|
||||
DSPercentReadsOther uint32
|
||||
DSPercentSearchesfromDRA uint32
|
||||
DSPercentSearchesfromKCC uint32
|
||||
DSPercentSearchesfromLDAP uint32
|
||||
DSPercentSearchesfromLSA uint32
|
||||
DSPercentSearchesfromNSPI uint32
|
||||
DSPercentSearchesfromNTDSAPI uint32
|
||||
DSPercentSearchesfromSAM uint32
|
||||
DSPercentSearchesOther uint32
|
||||
DSPercentWritesfromDRA uint32
|
||||
DSPercentWritesfromKCC uint32
|
||||
DSPercentWritesfromLDAP uint32
|
||||
DSPercentWritesfromLSA uint32
|
||||
DSPercentWritesfromNSPI uint32
|
||||
DSPercentWritesfromNTDSAPI uint32
|
||||
DSPercentWritesfromSAM uint32
|
||||
DSPercentWritesOther uint32
|
||||
DSSearchsuboperationsPersec uint32
|
||||
DSSecurityDescriptorPropagationsEvents uint32
|
||||
DSSecurityDescriptorPropagatorAverageExclusionTime uint32
|
||||
DSSecurityDescriptorPropagatorRuntimeQueue uint32
|
||||
DSSecurityDescriptorsuboperationsPersec uint32
|
||||
DSServerBindsPersec uint32
|
||||
DSServerNameTranslationsPersec uint32
|
||||
DSThreadsinUse uint32
|
||||
ExternalBindsPersec uint32
|
||||
FastBindsPersec uint32
|
||||
LDAPActiveThreads uint32
|
||||
LDAPBindTime uint32
|
||||
LDAPClientSessions uint32
|
||||
LDAPClosedConnectionsPersec uint32
|
||||
LDAPNewConnectionsPersec uint32
|
||||
LDAPNewSSLConnectionsPersec uint32
|
||||
LDAPSearchesPersec uint32
|
||||
LDAPSuccessfulBindsPersec uint32
|
||||
LDAPUDPoperationsPersec uint32
|
||||
LDAPWritesPersec uint32
|
||||
LinkValuesCleanedPersec uint32
|
||||
NegotiatedBindsPersec uint32
|
||||
NTLMBindsPersec uint32
|
||||
OnelevelsearchesPersec uint32
|
||||
PhantomsCleanedPersec uint32
|
||||
PhantomsVisitedPersec uint32
|
||||
SAMAccountGroupEvaluationLatency uint32
|
||||
SAMDisplayInformationQueriesPersec uint32
|
||||
SAMDomainLocalGroupMembershipEvaluationsPersec uint32
|
||||
SAMEnumerationsPersec uint32
|
||||
SAMGCEvaluationsPersec uint32
|
||||
SAMGlobalGroupMembershipEvaluationsPersec uint32
|
||||
SAMMachineCreationAttemptsPersec uint32
|
||||
SAMMembershipChangesPersec uint32
|
||||
SAMNonTransitiveMembershipEvaluationsPersec uint32
|
||||
SAMPasswordChangesPersec uint32
|
||||
SAMResourceGroupEvaluationLatency uint32
|
||||
SAMSuccessfulComputerCreationsPersecIncludesallrequests uint32
|
||||
SAMSuccessfulUserCreationsPersec uint32
|
||||
SAMTransitiveMembershipEvaluationsPersec uint32
|
||||
SAMUniversalGroupMembershipEvaluationsPersec uint32
|
||||
SAMUserCreationAttemptsPersec uint32
|
||||
SimpleBindsPersec uint32
|
||||
SubtreesearchesPersec uint32
|
||||
TombstonesGarbageCollectedPersec uint32
|
||||
TombstonesVisitedPersec uint32
|
||||
Transitiveoperationsmillisecondsrun uint32
|
||||
TransitiveoperationsPersec uint32
|
||||
TransitivesuboperationsPersec uint32
|
||||
}
|
||||
@@ -4,14 +4,15 @@ package adcs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -23,7 +24,8 @@ var ConfigDefaults = Config{}
|
||||
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
perfDataCollector perfdata.Collector
|
||||
|
||||
challengeResponseProcessingTime *prometheus.Desc
|
||||
challengeResponsesPerSecond *prometheus.Desc
|
||||
@@ -40,7 +42,7 @@ type Collector struct {
|
||||
signedCertificateTimestampListsPerSecond *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -49,8 +51,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -62,19 +62,44 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
if utils.PDHEnabled() {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
return []string{"Certification Authority"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
if utils.PDHEnabled() {
|
||||
counters := []string{
|
||||
requestsPerSecond,
|
||||
requestProcessingTime,
|
||||
retrievalsPerSecond,
|
||||
retrievalProcessingTime,
|
||||
failedRequestsPerSecond,
|
||||
issuedRequestsPerSecond,
|
||||
pendingRequestsPerSecond,
|
||||
requestCryptographicSigningTime,
|
||||
requestPolicyModuleProcessingTime,
|
||||
challengeResponsesPerSecond,
|
||||
challengeResponseProcessingTime,
|
||||
signedCertificateTimestampListsPerSecond,
|
||||
signedCertificateTimestampListProcessingTime,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Certification Authority", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Certification Authority collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.requestsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
|
||||
"Total certificate requests processed",
|
||||
@@ -157,49 +182,44 @@ func (c *Collector) Build() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if err := c.collectADCSCounters(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting ADCS metrics", "err", err)
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
if utils.PDHEnabled() {
|
||||
return c.collectPDH(ch)
|
||||
}
|
||||
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collectADCSCounters(ctx, logger, ch); err != nil {
|
||||
logger.Error("failed collecting ADCS metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type perflibADCS struct {
|
||||
Name string
|
||||
RequestsPerSecond float64 `perflib:"Requests/sec"`
|
||||
RequestProcessingTime float64 `perflib:"Request processing time (ms)"`
|
||||
RetrievalsPerSecond float64 `perflib:"Retrievals/sec"`
|
||||
RetrievalProcessingTime float64 `perflib:"Retrieval processing time (ms)"`
|
||||
FailedRequestsPerSecond float64 `perflib:"Failed Requests/sec"`
|
||||
IssuedRequestsPerSecond float64 `perflib:"Issued Requests/sec"`
|
||||
PendingRequestsPerSecond float64 `perflib:"Pending Requests/sec"`
|
||||
RequestCryptographicSigningTime float64 `perflib:"Request cryptographic signing time (ms)"`
|
||||
RequestPolicyModuleProcessingTime float64 `perflib:"Request policy module processing time (ms)"`
|
||||
ChallengeResponsesPerSecond float64 `perflib:"Challenge Responses/sec"`
|
||||
ChallengeResponseProcessingTime float64 `perflib:"Challenge Response processing time (ms)"`
|
||||
SignedCertificateTimestampListsPerSecond float64 `perflib:"Signed Certificate Timestamp Lists/sec"`
|
||||
SignedCertificateTimestampListProcessingTime float64 `perflib:"Signed Certificate Timestamp List processing time (ms)"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectADCSCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collectADCSCounters(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
dst := make([]perflibADCS, 0)
|
||||
|
||||
if _, ok := ctx.PerfObjects["Certification Authority"]; !ok {
|
||||
return errors.New("perflib did not contain an entry for Certification Authority")
|
||||
}
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, c.logger)
|
||||
|
||||
err := v1.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(dst) == 0 {
|
||||
return errors.New("perflib query for Certification Authority (ADCS) returned empty result set")
|
||||
}
|
||||
|
||||
for _, d := range dst {
|
||||
n := strings.ToLower(d.Name)
|
||||
if n == "" {
|
||||
if d.Name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
@@ -282,3 +302,97 @@ func (c *Collector) collectADCSCounters(ctx *types.ScrapeContext, ch chan<- prom
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect Certification Authority (ADCS) metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for Certification Authority (ADCS) returned empty result set")
|
||||
}
|
||||
|
||||
for name, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(data[requestProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retrievalsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
data[retrievalsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retrievalProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(data[retrievalProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failedRequestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
data[failedRequestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.issuedRequestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
data[issuedRequestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pendingRequestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
data[pendingRequestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestCryptographicSigningTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(data[requestCryptographicSigningTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestPolicyModuleProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(data[requestPolicyModuleProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.challengeResponsesPerSecond,
|
||||
prometheus.CounterValue,
|
||||
data[challengeResponsesPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.challengeResponseProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(data[challengeResponseProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.signedCertificateTimestampListsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
data[signedCertificateTimestampListsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.signedCertificateTimestampListProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(data[signedCertificateTimestampListProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package adcs_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adcs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/adcs"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
34
internal/collector/adcs/const.go
Normal file
34
internal/collector/adcs/const.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package adcs
|
||||
|
||||
const (
|
||||
challengeResponseProcessingTime = "Challenge Response processing time (ms)"
|
||||
challengeResponsesPerSecond = "Challenge Responses/sec"
|
||||
failedRequestsPerSecond = "Failed Requests/sec"
|
||||
issuedRequestsPerSecond = "Issued Requests/sec"
|
||||
pendingRequestsPerSecond = "Pending Requests/sec"
|
||||
requestCryptographicSigningTime = "Request cryptographic signing time (ms)"
|
||||
requestPolicyModuleProcessingTime = "Request policy module processing time (ms)"
|
||||
requestProcessingTime = "Request processing time (ms)"
|
||||
requestsPerSecond = "Requests/sec"
|
||||
retrievalProcessingTime = "Retrieval processing time (ms)"
|
||||
retrievalsPerSecond = "Retrievals/sec"
|
||||
signedCertificateTimestampListProcessingTime = "Signed Certificate Timestamp List processing time (ms)"
|
||||
signedCertificateTimestampListsPerSecond = "Signed Certificate Timestamp Lists/sec"
|
||||
)
|
||||
|
||||
type perflibADCS struct {
|
||||
Name string
|
||||
RequestsPerSecond float64 `perflib:"Requests/sec"`
|
||||
RequestProcessingTime float64 `perflib:"Request processing time (ms)"`
|
||||
RetrievalsPerSecond float64 `perflib:"Retrievals/sec"`
|
||||
RetrievalProcessingTime float64 `perflib:"Retrieval processing time (ms)"`
|
||||
FailedRequestsPerSecond float64 `perflib:"Failed Requests/sec"`
|
||||
IssuedRequestsPerSecond float64 `perflib:"Issued Requests/sec"`
|
||||
PendingRequestsPerSecond float64 `perflib:"Pending Requests/sec"`
|
||||
RequestCryptographicSigningTime float64 `perflib:"Request cryptographic signing time (ms)"`
|
||||
RequestPolicyModuleProcessingTime float64 `perflib:"Request policy module processing time (ms)"`
|
||||
ChallengeResponsesPerSecond float64 `perflib:"Challenge Responses/sec"`
|
||||
ChallengeResponseProcessingTime float64 `perflib:"Challenge Response processing time (ms)"`
|
||||
SignedCertificateTimestampListsPerSecond float64 `perflib:"Signed Certificate Timestamp Lists/sec"`
|
||||
SignedCertificateTimestampListProcessingTime float64 `perflib:"Signed Certificate Timestamp List processing time (ms)"`
|
||||
}
|
||||
@@ -3,12 +3,19 @@
|
||||
package adfs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"math"
|
||||
"slices"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -20,7 +27,8 @@ var ConfigDefaults = Config{}
|
||||
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
perfDataCollector perfdata.Collector
|
||||
|
||||
adLoginConnectionFailures *prometheus.Desc
|
||||
artifactDBFailures *prometheus.Desc
|
||||
@@ -63,11 +71,11 @@ type Collector struct {
|
||||
upAuthenticationFailures *prometheus.Desc
|
||||
upAuthentications *prometheus.Desc
|
||||
windowsIntegratedAuthentications *prometheus.Desc
|
||||
wsfedTokenRequests *prometheus.Desc
|
||||
wstrustTokenRequests *prometheus.Desc
|
||||
wsFedTokenRequests *prometheus.Desc
|
||||
wsTrustTokenRequests *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -76,8 +84,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -89,19 +95,74 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
if utils.PDHEnabled() {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
return []string{"AD FS"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
if utils.PDHEnabled() {
|
||||
counters := []string{
|
||||
adLoginConnectionFailures,
|
||||
certificateAuthentications,
|
||||
deviceAuthentications,
|
||||
extranetAccountLockouts,
|
||||
federatedAuthentications,
|
||||
passportAuthentications,
|
||||
passiveRequests,
|
||||
passwordChangeFailed,
|
||||
passwordChangeSucceeded,
|
||||
tokenRequests,
|
||||
windowsIntegratedAuthentications,
|
||||
oAuthAuthZRequests,
|
||||
oAuthClientAuthentications,
|
||||
oAuthClientAuthenticationFailures,
|
||||
oAuthClientCredentialRequestFailures,
|
||||
oAuthClientCredentialRequests,
|
||||
oAuthClientPrivateKeyJWTAuthenticationFailures,
|
||||
oAuthClientPrivateKeyJWTAuthentications,
|
||||
oAuthClientBasicAuthenticationFailures,
|
||||
oAuthClientBasicAuthentications,
|
||||
oAuthClientSecretPostAuthenticationFailures,
|
||||
oAuthClientSecretPostAuthentications,
|
||||
oAuthClientWindowsAuthenticationFailures,
|
||||
oAuthClientWindowsAuthentications,
|
||||
oAuthLogonCertRequestFailures,
|
||||
oAuthLogonCertTokenRequests,
|
||||
oAuthPasswordGrantRequestFailures,
|
||||
oAuthPasswordGrantRequests,
|
||||
oAuthTokenRequests,
|
||||
samlPTokenRequests,
|
||||
ssoAuthenticationFailures,
|
||||
ssoAuthentications,
|
||||
wsFedTokenRequests,
|
||||
wsTrustTokenRequests,
|
||||
usernamePasswordAuthenticationFailures,
|
||||
usernamePasswordAuthentications,
|
||||
externalAuthentications,
|
||||
externalAuthNFailures,
|
||||
artifactDBFailures,
|
||||
avgArtifactDBQueryTime,
|
||||
configDBFailures,
|
||||
avgConfigDBQueryTime,
|
||||
federationMetadataRequests,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "AD FS", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create AD FS collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.adLoginConnectionFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ad_login_connection_failures_total"),
|
||||
"Total number of connection failures to an Active Directory domain controller",
|
||||
@@ -294,13 +355,13 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.wsfedTokenRequests = prometheus.NewDesc(
|
||||
c.wsFedTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wsfed_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Fed protocol",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.wstrustTokenRequests = prometheus.NewDesc(
|
||||
c.wsTrustTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wstrust_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Trust protocol",
|
||||
nil,
|
||||
@@ -364,55 +425,20 @@ func (c *Collector) Build() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type perflibADFS struct {
|
||||
AdLoginConnectionFailures float64 `perflib:"AD Login Connection Failures"`
|
||||
CertificateAuthentications float64 `perflib:"Certificate Authentications"`
|
||||
DeviceAuthentications float64 `perflib:"Device Authentications"`
|
||||
ExtranetAccountLockouts float64 `perflib:"Extranet Account Lockouts"`
|
||||
FederatedAuthentications float64 `perflib:"Federated Authentications"`
|
||||
PassportAuthentications float64 `perflib:"Microsoft Passport Authentications"`
|
||||
PassiveRequests float64 `perflib:"Passive Requests"`
|
||||
PasswordChangeFailed float64 `perflib:"Password Change Failed Requests"`
|
||||
PasswordChangeSucceeded float64 `perflib:"Password Change Successful Requests"`
|
||||
TokenRequests float64 `perflib:"Token Requests"`
|
||||
WindowsIntegratedAuthentications float64 `perflib:"Windows Integrated Authentications"`
|
||||
OAuthAuthZRequests float64 `perflib:"OAuth AuthZ Requests"`
|
||||
OAuthClientAuthentications float64 `perflib:"OAuth Client Authentications"`
|
||||
OAuthClientAuthenticationFailures float64 `perflib:"OAuth Client Authentications Failures"`
|
||||
OAuthClientCredentialRequestFailures float64 `perflib:"OAuth Client Credentials Request Failures"`
|
||||
OAuthClientCredentialRequests float64 `perflib:"OAuth Client Credentials Requests"`
|
||||
OAuthClientPrivKeyJWTAuthnFailures float64 `perflib:"OAuth Client Private Key Jwt Authentication Failures"`
|
||||
OAuthClientPrivKeyJWTAuthentications float64 `perflib:"OAuth Client Private Key Jwt Authentications"`
|
||||
OAuthClientBasicAuthnFailures float64 `perflib:"OAuth Client Secret Basic Authentication Failures"`
|
||||
OAuthClientBasicAuthentications float64 `perflib:"OAuth Client Secret Basic Authentication Requests"`
|
||||
OAuthClientSecretPostAuthnFailures float64 `perflib:"OAuth Client Secret Post Authentication Failures"`
|
||||
OAuthClientSecretPostAuthentications float64 `perflib:"OAuth Client Secret Post Authentications"`
|
||||
OAuthClientWindowsAuthnFailures float64 `perflib:"OAuth Client Windows Integrated Authentication Failures"`
|
||||
OAuthClientWindowsAuthentications float64 `perflib:"OAuth Client Windows Integrated Authentications"`
|
||||
OAuthLogonCertRequestFailures float64 `perflib:"OAuth Logon Certificate Request Failures"`
|
||||
OAuthLogonCertTokenRequests float64 `perflib:"OAuth Logon Certificate Token Requests"`
|
||||
OAuthPasswordGrantRequestFailures float64 `perflib:"OAuth Password Grant Request Failures"`
|
||||
OAuthPasswordGrantRequests float64 `perflib:"OAuth Password Grant Requests"`
|
||||
OAuthTokenRequests float64 `perflib:"OAuth Token Requests"`
|
||||
SAMLPTokenRequests float64 `perflib:"SAML-P Token Requests"`
|
||||
SSOAuthenticationFailures float64 `perflib:"SSO Authentication Failures"`
|
||||
SSOAuthentications float64 `perflib:"SSO Authentications"`
|
||||
WSFedTokenRequests float64 `perflib:"WS-Fed Token Requests"`
|
||||
WSTrustTokenRequests float64 `perflib:"WS-Trust Token Requests"`
|
||||
UsernamePasswordAuthnFailures float64 `perflib:"U/P Authentication Failures"`
|
||||
UsernamePasswordAuthentications float64 `perflib:"U/P Authentications"`
|
||||
ExternalAuthentications float64 `perflib:"External Authentications"`
|
||||
ExternalAuthNFailures float64 `perflib:"External Authentication Failures"`
|
||||
ArtifactDBFailures float64 `perflib:"Artifact Database Connection Failures"`
|
||||
AvgArtifactDBQueryTime float64 `perflib:"Average Artifact Database Query Time"`
|
||||
ConfigDBFailures float64 `perflib:"Configuration Database Connection Failures"`
|
||||
AvgConfigDBQueryTime float64 `perflib:"Average Config Database Query Time"`
|
||||
FederationMetadataRequests float64 `perflib:"Federation Metadata Requests"`
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
if utils.PDHEnabled() {
|
||||
return c.collectPDH(ch)
|
||||
}
|
||||
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
return c.collect(ctx, logger, ch)
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var adfsData []perflibADFS
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, c.logger)
|
||||
|
||||
err := v1.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -610,13 +636,13 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.wsfedTokenRequests,
|
||||
c.wsFedTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].WSFedTokenRequests,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.wstrustTokenRequests,
|
||||
c.wsTrustTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].WSTrustTokenRequests,
|
||||
)
|
||||
@@ -674,5 +700,285 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].FederationMetadataRequests,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
|
||||
data, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect ADFS metrics: %w", err)
|
||||
}
|
||||
|
||||
instanceKey := slices.Collect(maps.Keys(data))
|
||||
|
||||
if len(instanceKey) == 0 {
|
||||
return errors.New("perflib query for ADFS returned empty result set")
|
||||
}
|
||||
|
||||
adfsData, ok := data[instanceKey[0]]
|
||||
|
||||
if !ok {
|
||||
return errors.New("perflib query for ADFS returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.adLoginConnectionFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[adLoginConnectionFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.certificateAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[certificateAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.deviceAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[deviceAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.extranetAccountLockouts,
|
||||
prometheus.CounterValue,
|
||||
adfsData[extranetAccountLockouts].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.federatedAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[federatedAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passportAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[passportAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passiveRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[passiveRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passwordChangeFailed,
|
||||
prometheus.CounterValue,
|
||||
adfsData[passwordChangeFailed].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passwordChangeSucceeded,
|
||||
prometheus.CounterValue,
|
||||
adfsData[passwordChangeSucceeded].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.tokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[tokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.windowsIntegratedAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[windowsIntegratedAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthAuthZRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthAuthZRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientAuthenticationsFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientCredentialsRequestFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientCredentialRequestFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientCredentialsRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientCredentialRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientPrivateKeyJwtAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientPrivateKeyJWTAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientPrivateKeyJwtAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientPrivateKeyJWTAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretBasicAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientBasicAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretBasicAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientBasicAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretPostAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientSecretPostAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretPostAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientSecretPostAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientWindowsIntegratedAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientWindowsAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientWindowsIntegratedAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthClientWindowsAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthLogonCertificateRequestFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthLogonCertRequestFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthLogonCertificateTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthLogonCertTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthPasswordGrantRequestFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthPasswordGrantRequestFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthPasswordGrantRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthPasswordGrantRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[oAuthTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.samlPTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[samlPTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ssoAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[ssoAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ssoAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[ssoAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.wsFedTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[wsFedTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.wsTrustTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[wsTrustTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.upAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[usernamePasswordAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.upAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[usernamePasswordAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[externalAuthNFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[externalAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.artifactDBFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[artifactDBFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.avgArtifactDBQueryTime,
|
||||
prometheus.CounterValue,
|
||||
adfsData[avgArtifactDBQueryTime].FirstValue*math.Pow(10, -8),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.configDBFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[configDBFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.avgConfigDBQueryTime,
|
||||
prometheus.CounterValue,
|
||||
adfsData[avgConfigDBQueryTime].FirstValue*math.Pow(10, -8),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.federationMetadataRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[federationMetadataRequests].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package adfs_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adfs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/adfs"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
93
internal/collector/adfs/const.go
Normal file
93
internal/collector/adfs/const.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package adfs
|
||||
|
||||
const (
|
||||
adLoginConnectionFailures = "AD Login Connection Failures"
|
||||
artifactDBFailures = "Artifact Database Connection Failures"
|
||||
avgArtifactDBQueryTime = "Average Artifact Database Query Time"
|
||||
avgConfigDBQueryTime = "Average Config Database Query Time"
|
||||
certificateAuthentications = "Certificate Authentications"
|
||||
configDBFailures = "Configuration Database Connection Failures"
|
||||
deviceAuthentications = "Device Authentications"
|
||||
externalAuthentications = "External Authentications"
|
||||
externalAuthNFailures = "External Authentication Failures"
|
||||
extranetAccountLockouts = "Extranet Account Lockouts"
|
||||
federatedAuthentications = "Federated Authentications"
|
||||
federationMetadataRequests = "Federation Metadata Requests"
|
||||
oAuthAuthZRequests = "OAuth AuthZ Requests"
|
||||
oAuthClientAuthenticationFailures = "OAuth Client Authentications Failures"
|
||||
oAuthClientAuthentications = "OAuth Client Authentications"
|
||||
oAuthClientBasicAuthenticationFailures = "OAuth Client Secret Basic Authentication Failures"
|
||||
oAuthClientBasicAuthentications = "OAuth Client Secret Basic Authentication Requests"
|
||||
oAuthClientCredentialRequestFailures = "OAuth Client Credentials Request Failures"
|
||||
oAuthClientCredentialRequests = "OAuth Client Credentials Requests"
|
||||
oAuthClientPrivateKeyJWTAuthenticationFailures = "OAuth Client Private Key Jwt Authentication Failures"
|
||||
oAuthClientPrivateKeyJWTAuthentications = "OAuth Client Private Key Jwt Authentications"
|
||||
oAuthClientSecretPostAuthenticationFailures = "OAuth Client Secret Post Authentication Failures"
|
||||
oAuthClientSecretPostAuthentications = "OAuth Client Secret Post Authentications"
|
||||
oAuthClientWindowsAuthenticationFailures = "OAuth Client Windows Integrated Authentication Failures"
|
||||
oAuthClientWindowsAuthentications = "OAuth Client Windows Integrated Authentications"
|
||||
oAuthLogonCertRequestFailures = "OAuth Logon Certificate Request Failures"
|
||||
oAuthLogonCertTokenRequests = "OAuth Logon Certificate Token Requests"
|
||||
oAuthPasswordGrantRequestFailures = "OAuth Password Grant Request Failures"
|
||||
oAuthPasswordGrantRequests = "OAuth Password Grant Requests"
|
||||
oAuthTokenRequests = "OAuth Token Requests"
|
||||
passiveRequests = "Passive Requests"
|
||||
passportAuthentications = "Microsoft Passport Authentications"
|
||||
passwordChangeFailed = "Password Change Failed Requests"
|
||||
passwordChangeSucceeded = "Password Change Successful Requests"
|
||||
samlPTokenRequests = "SAML-P Token Requests"
|
||||
ssoAuthenticationFailures = "SSO Authentication Failures"
|
||||
ssoAuthentications = "SSO Authentications"
|
||||
tokenRequests = "Token Requests"
|
||||
usernamePasswordAuthenticationFailures = "U/P Authentication Failures"
|
||||
usernamePasswordAuthentications = "U/P Authentications"
|
||||
windowsIntegratedAuthentications = "Windows Integrated Authentications"
|
||||
wsFedTokenRequests = "WS-Fed Token Requests"
|
||||
wsTrustTokenRequests = "WS-Trust Token Requests"
|
||||
)
|
||||
|
||||
type perflibADFS struct {
|
||||
AdLoginConnectionFailures float64 `perflib:"AD Login Connection Failures"`
|
||||
CertificateAuthentications float64 `perflib:"Certificate Authentications"`
|
||||
DeviceAuthentications float64 `perflib:"Device Authentications"`
|
||||
ExtranetAccountLockouts float64 `perflib:"Extranet Account Lockouts"`
|
||||
FederatedAuthentications float64 `perflib:"Federated Authentications"`
|
||||
PassportAuthentications float64 `perflib:"Microsoft Passport Authentications"`
|
||||
PassiveRequests float64 `perflib:"Passive Requests"`
|
||||
PasswordChangeFailed float64 `perflib:"Password Change Failed Requests"`
|
||||
PasswordChangeSucceeded float64 `perflib:"Password Change Successful Requests"`
|
||||
TokenRequests float64 `perflib:"Token Requests"`
|
||||
WindowsIntegratedAuthentications float64 `perflib:"Windows Integrated Authentications"`
|
||||
OAuthAuthZRequests float64 `perflib:"OAuth AuthZ Requests"`
|
||||
OAuthClientAuthentications float64 `perflib:"OAuth Client Authentications"`
|
||||
OAuthClientAuthenticationFailures float64 `perflib:"OAuth Client Authentications Failures"`
|
||||
OAuthClientCredentialRequestFailures float64 `perflib:"OAuth Client Credentials Request Failures"`
|
||||
OAuthClientCredentialRequests float64 `perflib:"OAuth Client Credentials Requests"`
|
||||
OAuthClientPrivKeyJWTAuthnFailures float64 `perflib:"OAuth Client Private Key Jwt Authentication Failures"`
|
||||
OAuthClientPrivKeyJWTAuthentications float64 `perflib:"OAuth Client Private Key Jwt Authentications"`
|
||||
OAuthClientBasicAuthnFailures float64 `perflib:"OAuth Client Secret Basic Authentication Failures"`
|
||||
OAuthClientBasicAuthentications float64 `perflib:"OAuth Client Secret Basic Authentication Requests"`
|
||||
OAuthClientSecretPostAuthnFailures float64 `perflib:"OAuth Client Secret Post Authentication Failures"`
|
||||
OAuthClientSecretPostAuthentications float64 `perflib:"OAuth Client Secret Post Authentications"`
|
||||
OAuthClientWindowsAuthnFailures float64 `perflib:"OAuth Client Windows Integrated Authentication Failures"`
|
||||
OAuthClientWindowsAuthentications float64 `perflib:"OAuth Client Windows Integrated Authentications"`
|
||||
OAuthLogonCertRequestFailures float64 `perflib:"OAuth Logon Certificate Request Failures"`
|
||||
OAuthLogonCertTokenRequests float64 `perflib:"OAuth Logon Certificate Token Requests"`
|
||||
OAuthPasswordGrantRequestFailures float64 `perflib:"OAuth Password Grant Request Failures"`
|
||||
OAuthPasswordGrantRequests float64 `perflib:"OAuth Password Grant Requests"`
|
||||
OAuthTokenRequests float64 `perflib:"OAuth Token Requests"`
|
||||
SAMLPTokenRequests float64 `perflib:"SAML-P Token Requests"`
|
||||
SSOAuthenticationFailures float64 `perflib:"SSO Authentication Failures"`
|
||||
SSOAuthentications float64 `perflib:"SSO Authentications"`
|
||||
WSFedTokenRequests float64 `perflib:"WS-Fed Token Requests"`
|
||||
WSTrustTokenRequests float64 `perflib:"WS-Trust Token Requests"`
|
||||
UsernamePasswordAuthnFailures float64 `perflib:"U/P Authentication Failures"`
|
||||
UsernamePasswordAuthentications float64 `perflib:"U/P Authentications"`
|
||||
ExternalAuthentications float64 `perflib:"External Authentications"`
|
||||
ExternalAuthNFailures float64 `perflib:"External Authentication Failures"`
|
||||
ArtifactDBFailures float64 `perflib:"Artifact Database Connection Failures"`
|
||||
AvgArtifactDBQueryTime float64 `perflib:"Average Artifact Database Query Time"`
|
||||
ConfigDBFailures float64 `perflib:"Configuration Database Connection Failures"`
|
||||
AvgConfigDBQueryTime float64 `perflib:"Average Config Database Query Time"`
|
||||
FederationMetadataRequests float64 `perflib:"Federation Metadata Requests"`
|
||||
}
|
||||
@@ -3,12 +3,17 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -21,7 +26,8 @@ var ConfigDefaults = Config{}
|
||||
// A Collector is a Prometheus Collector for Perflib Cache metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
perfDataCollector perfdata.Collector
|
||||
|
||||
asyncCopyReadsTotal *prometheus.Desc
|
||||
asyncDataMapsTotal *prometheus.Desc
|
||||
@@ -54,7 +60,7 @@ type Collector struct {
|
||||
syncPinReadsTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -63,8 +69,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -76,19 +80,60 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
if utils.PDHEnabled() {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
return []string{"Cache"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
if utils.PDHEnabled() {
|
||||
counters := []string{
|
||||
asyncCopyReadsTotal,
|
||||
asyncDataMapsTotal,
|
||||
asyncFastReadsTotal,
|
||||
asyncMDLReadsTotal,
|
||||
asyncPinReadsTotal,
|
||||
copyReadHitsTotal,
|
||||
copyReadsTotal,
|
||||
dataFlushesTotal,
|
||||
dataFlushPagesTotal,
|
||||
dataMapHitsPercent,
|
||||
dataMapPinsTotal,
|
||||
dataMapsTotal,
|
||||
dirtyPages,
|
||||
dirtyPageThreshold,
|
||||
fastReadNotPossiblesTotal,
|
||||
fastReadResourceMissesTotal,
|
||||
fastReadsTotal,
|
||||
lazyWriteFlushesTotal,
|
||||
lazyWritePagesTotal,
|
||||
mdlReadHitsTotal,
|
||||
mdlReadsTotal,
|
||||
pinReadHitsTotal,
|
||||
pinReadsTotal,
|
||||
readAheadsTotal,
|
||||
syncCopyReadsTotal,
|
||||
syncDataMapsTotal,
|
||||
syncFastReadsTotal,
|
||||
syncMDLReadsTotal,
|
||||
syncPinReadsTotal,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Cache", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Cache collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.asyncCopyReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "async_copy_reads_total"),
|
||||
"(AsyncCopyReadsTotal)",
|
||||
@@ -263,13 +308,21 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect implements the Collector interface.
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cache metrics", "err", err)
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
if utils.PDHEnabled() {
|
||||
return c.collectPDH(ch)
|
||||
}
|
||||
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ctx, logger, ch); err != nil {
|
||||
logger.Error("failed collecting cache metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -277,43 +330,10 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
||||
return nil
|
||||
}
|
||||
|
||||
// Perflib "Cache":
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85)
|
||||
type perflibCache struct {
|
||||
AsyncCopyReadsTotal float64 `perflib:"Async Copy Reads/sec"`
|
||||
AsyncDataMapsTotal float64 `perflib:"Async Data Maps/sec"`
|
||||
AsyncFastReadsTotal float64 `perflib:"Async Fast Reads/sec"`
|
||||
AsyncMDLReadsTotal float64 `perflib:"Async MDL Reads/sec"`
|
||||
AsyncPinReadsTotal float64 `perflib:"Async Pin Reads/sec"`
|
||||
CopyReadHitsTotal float64 `perflib:"Copy Read Hits/sec"`
|
||||
CopyReadsTotal float64 `perflib:"Copy Reads/sec"`
|
||||
DataFlushesTotal float64 `perflib:"Data Flushes/sec"`
|
||||
DataFlushPagesTotal float64 `perflib:"Data Flush Pages/sec"`
|
||||
DataMapPinsTotal float64 `perflib:"Data Map Pins/sec"`
|
||||
DataMapsTotal float64 `perflib:"Data Maps/sec"`
|
||||
FastReadNotPossiblesTotal float64 `perflib:"Fast Read Not Possibles/sec"`
|
||||
FastReadResourceMissesTotal float64 `perflib:"Fast Read Resource Misses/sec"`
|
||||
FastReadsTotal float64 `perflib:"Fast Reads/sec"`
|
||||
LazyWriteFlushesTotal float64 `perflib:"Lazy Write Flushes/sec"`
|
||||
LazyWritePagesTotal float64 `perflib:"Lazy Write Pages/sec"`
|
||||
MDLReadHitsTotal float64 `perflib:"MDL Read Hits/sec"`
|
||||
MDLReadsTotal float64 `perflib:"MDL Reads/sec"`
|
||||
PinReadHitsTotal float64 `perflib:"Pin Read Hits/sec"`
|
||||
PinReadsTotal float64 `perflib:"Pin Reads/sec"`
|
||||
ReadAheadsTotal float64 `perflib:"Read Aheads/sec"`
|
||||
SyncCopyReadsTotal float64 `perflib:"Sync Copy Reads/sec"`
|
||||
SyncDataMapsTotal float64 `perflib:"Sync Data Maps/sec"`
|
||||
SyncFastReadsTotal float64 `perflib:"Sync Fast Reads/sec"`
|
||||
SyncMDLReadsTotal float64 `perflib:"Sync MDL Reads/sec"`
|
||||
SyncPinReadsTotal float64 `perflib:"Sync Pin Reads/sec"`
|
||||
DirtyPages float64 `perflib:"Dirty Pages"`
|
||||
DirtyPageThreshold float64 `perflib:"Dirty Page Threshold"`
|
||||
DataMapHitsPercent float64 `perflib:"Data Map Hits %"`
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var dst []perflibCache // Single-instance class, array is required but will have single entry.
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, c.logger); err != nil {
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -326,146 +346,363 @@ func (c *Collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncCopyReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncDataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncDataMapsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncFastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncFastReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncMDLReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncMDLReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncPinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncPinReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.copyReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].CopyReadHitsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.copyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].CopyReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataFlushesTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataFlushPagesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataFlushPagesTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapPinsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataMapPinsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataMapsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadNotPossiblesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadNotPossiblesTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadResourceMissesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadResourceMissesTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWriteFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].LazyWriteFlushesTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWritePagesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].LazyWritePagesTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].MDLReadHitsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].MDLReadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PinReadHitsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PinReadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readAheadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].ReadAheadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncCopyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncCopyReadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncDataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncDataMapsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncFastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncFastReadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncMDLReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncMDLReadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncPinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncPinReadsTotal,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPages,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DirtyPages,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPageThreshold,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DirtyPageThreshold,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapHitsPercent,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DataMapHitsPercent,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapPinsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataMapPinsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataMapsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPages,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DirtyPages,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPageThreshold,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DirtyPageThreshold,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadNotPossiblesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadNotPossiblesTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadResourceMissesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadResourceMissesTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWriteFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].LazyWriteFlushesTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWritePagesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].LazyWritePagesTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].MDLReadHitsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].MDLReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PinReadHitsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PinReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readAheadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].ReadAheadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncCopyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncCopyReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncDataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncDataMapsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncFastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncFastReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncMDLReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncMDLReadsTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncPinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncPinReadsTotal,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
|
||||
data, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect Cache metrics: %w", err)
|
||||
}
|
||||
|
||||
cacheData, ok := data[perftypes.EmptyInstance]
|
||||
|
||||
if !ok {
|
||||
return errors.New("perflib query for Cache returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncCopyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[asyncCopyReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncDataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[asyncDataMapsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncFastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[asyncFastReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncMDLReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[asyncMDLReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncPinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[asyncPinReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.copyReadHitsTotal,
|
||||
prometheus.GaugeValue,
|
||||
cacheData[copyReadHitsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.copyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[copyReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[dataFlushesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataFlushPagesTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[dataFlushPagesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapHitsPercent,
|
||||
prometheus.GaugeValue,
|
||||
cacheData[dataMapHitsPercent].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapPinsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[dataMapPinsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[dataMapsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPages,
|
||||
prometheus.GaugeValue,
|
||||
cacheData[dirtyPages].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPageThreshold,
|
||||
prometheus.GaugeValue,
|
||||
cacheData[dirtyPageThreshold].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadNotPossiblesTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[fastReadNotPossiblesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadResourceMissesTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[fastReadResourceMissesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[fastReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWriteFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[lazyWriteFlushesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWritePagesTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[lazyWritePagesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[mdlReadHitsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[mdlReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[pinReadHitsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[pinReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readAheadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[readAheadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncCopyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[syncCopyReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncDataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[syncDataMapsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncFastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[syncFastReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncMDLReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[syncMDLReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncPinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
cacheData[syncPinReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package cache_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cache"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cache"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
69
internal/collector/cache/const.go
vendored
Normal file
69
internal/collector/cache/const.go
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package cache
|
||||
|
||||
// Perflib "Cache":
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85)
|
||||
const (
|
||||
asyncCopyReadsTotal = "Async Copy Reads/sec"
|
||||
asyncDataMapsTotal = "Async Data Maps/sec"
|
||||
asyncFastReadsTotal = "Async Fast Reads/sec"
|
||||
asyncMDLReadsTotal = "Async MDL Reads/sec"
|
||||
asyncPinReadsTotal = "Async Pin Reads/sec"
|
||||
copyReadHitsTotal = "Copy Read Hits %"
|
||||
copyReadsTotal = "Copy Reads/sec"
|
||||
dataFlushesTotal = "Data Flushes/sec"
|
||||
dataFlushPagesTotal = "Data Flush Pages/sec"
|
||||
dataMapHitsPercent = "Data Map Hits %"
|
||||
dataMapPinsTotal = "Data Map Pins/sec"
|
||||
dataMapsTotal = "Data Maps/sec"
|
||||
dirtyPages = "Dirty Pages"
|
||||
dirtyPageThreshold = "Dirty Page Threshold"
|
||||
fastReadNotPossiblesTotal = "Fast Read Not Possibles/sec"
|
||||
fastReadResourceMissesTotal = "Fast Read Resource Misses/sec"
|
||||
fastReadsTotal = "Fast Reads/sec"
|
||||
lazyWriteFlushesTotal = "Lazy Write Flushes/sec"
|
||||
lazyWritePagesTotal = "Lazy Write Pages/sec"
|
||||
mdlReadHitsTotal = "MDL Read Hits %"
|
||||
mdlReadsTotal = "MDL Reads/sec"
|
||||
pinReadHitsTotal = "Pin Read Hits %"
|
||||
pinReadsTotal = "Pin Reads/sec"
|
||||
readAheadsTotal = "Read Aheads/sec"
|
||||
syncCopyReadsTotal = "Sync Copy Reads/sec"
|
||||
syncDataMapsTotal = "Sync Data Maps/sec"
|
||||
syncFastReadsTotal = "Sync Fast Reads/sec"
|
||||
syncMDLReadsTotal = "Sync MDL Reads/sec"
|
||||
syncPinReadsTotal = "Sync Pin Reads/sec"
|
||||
)
|
||||
|
||||
// Perflib "Cache":
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85)
|
||||
type perflibCache struct {
|
||||
AsyncCopyReadsTotal float64 `perflib:"Async Copy Reads/sec"`
|
||||
AsyncDataMapsTotal float64 `perflib:"Async Data Maps/sec"`
|
||||
AsyncFastReadsTotal float64 `perflib:"Async Fast Reads/sec"`
|
||||
AsyncMDLReadsTotal float64 `perflib:"Async MDL Reads/sec"`
|
||||
AsyncPinReadsTotal float64 `perflib:"Async Pin Reads/sec"`
|
||||
CopyReadHitsTotal float64 `perflib:"Copy Read Hits %"`
|
||||
CopyReadsTotal float64 `perflib:"Copy Reads/sec"`
|
||||
DataFlushesTotal float64 `perflib:"Data Flushes/sec"`
|
||||
DataFlushPagesTotal float64 `perflib:"Data Flush Pages/sec"`
|
||||
DataMapHitsPercent float64 `perflib:"Data Map Hits %"`
|
||||
DataMapPinsTotal float64 `perflib:"Data Map Pins/sec"`
|
||||
DataMapsTotal float64 `perflib:"Data Maps/sec"`
|
||||
DirtyPages float64 `perflib:"Dirty Pages"`
|
||||
DirtyPageThreshold float64 `perflib:"Dirty Page Threshold"`
|
||||
FastReadNotPossiblesTotal float64 `perflib:"Fast Read Not Possibles/sec"`
|
||||
FastReadResourceMissesTotal float64 `perflib:"Fast Read Resource Misses/sec"`
|
||||
FastReadsTotal float64 `perflib:"Fast Reads/sec"`
|
||||
LazyWriteFlushesTotal float64 `perflib:"Lazy Write Flushes/sec"`
|
||||
LazyWritePagesTotal float64 `perflib:"Lazy Write Pages/sec"`
|
||||
MDLReadHitsTotal float64 `perflib:"MDL Read Hits %"`
|
||||
MDLReadsTotal float64 `perflib:"MDL Reads/sec"`
|
||||
PinReadHitsTotal float64 `perflib:"Pin Read Hits %"`
|
||||
PinReadsTotal float64 `perflib:"Pin Reads/sec"`
|
||||
ReadAheadsTotal float64 `perflib:"Read Aheads/sec"`
|
||||
SyncCopyReadsTotal float64 `perflib:"Sync Copy Reads/sec"`
|
||||
SyncDataMapsTotal float64 `perflib:"Sync Data Maps/sec"`
|
||||
SyncFastReadsTotal float64 `perflib:"Sync Fast Reads/sec"`
|
||||
SyncMDLReadsTotal float64 `perflib:"Sync MDL Reads/sec"`
|
||||
SyncPinReadsTotal float64 `perflib:"Sync Pin Reads/sec"`
|
||||
}
|
||||
@@ -3,14 +3,16 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -23,7 +25,6 @@ var ConfigDefaults = Config{}
|
||||
// A Collector is a Prometheus Collector for containers metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
// Presence
|
||||
containerAvailable *prometheus.Desc
|
||||
@@ -57,7 +58,7 @@ type Collector struct {
|
||||
}
|
||||
|
||||
// New constructs a new Collector.
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -66,8 +67,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -79,19 +78,15 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
c.containerAvailable = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "available"),
|
||||
"Available",
|
||||
@@ -200,32 +195,33 @@ func (c *Collector) Build() error {
|
||||
[]string{"container_id"},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting collector metrics", "err", err)
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(logger, ch); err != nil {
|
||||
logger.Error("failed collecting collector metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// containerClose closes the container resource.
|
||||
func (c *Collector) containerClose(container hcsshim.Container) {
|
||||
err := container.Close()
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
// Types Container is passed to get the containers compute systems only
|
||||
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "Err in Getting containers", "err", err)
|
||||
logger.Error("Err in Getting containers",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -236,129 +232,181 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
prometheus.GaugeValue,
|
||||
float64(count),
|
||||
)
|
||||
|
||||
if count == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
containerPrefixes := make(map[string]string)
|
||||
collectErrors := make([]error, 0, len(containers))
|
||||
|
||||
for _, containerDetails := range containers {
|
||||
// https://stackoverflow.com/questions/45617758/proper-way-to-release-resources-with-defer-in-a-loop
|
||||
func() {
|
||||
container, err := hcsshim.OpenContainer(containerDetails.ID)
|
||||
if container != nil {
|
||||
defer c.containerClose(container)
|
||||
}
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "err in opening container", "containerId", containerDetails.ID, "err", err)
|
||||
return
|
||||
containerIdWithPrefix := getContainerIdWithPrefix(containerDetails)
|
||||
|
||||
if err = c.collectContainer(logger, ch, containerDetails, containerIdWithPrefix); err != nil {
|
||||
if hcsshim.IsNotExist(err) {
|
||||
logger.Debug("err in fetching container statistics",
|
||||
slog.String("container_id", containerDetails.ID),
|
||||
slog.Any("err", err),
|
||||
)
|
||||
} else {
|
||||
logger.Error("err in fetching container statistics",
|
||||
slog.String("container_id", containerDetails.ID),
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
collectErrors = append(collectErrors, err)
|
||||
}
|
||||
|
||||
cstats, err := container.Statistics()
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "err in fetching container Statistics", "containerId", containerDetails.ID, "err", err)
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
containerIdWithPrefix := getContainerIdWithPrefix(containerDetails)
|
||||
containerPrefixes[containerDetails.ID] = containerIdWithPrefix
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.containerAvailable,
|
||||
prometheus.CounterValue,
|
||||
1,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.usageCommitBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsageCommitBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.usageCommitPeakBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsageCommitPeakBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.usagePrivateWorkingSetBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(cstats.Memory.UsagePrivateWorkingSetBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeTotal,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.TotalRuntime100ns)*perflib.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeUser,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.RuntimeUser100ns)*perflib.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeKernel,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Processor.RuntimeKernel100ns)*perflib.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.ReadCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.ReadSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.writeCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.WriteCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.writeSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(cstats.Storage.WriteSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
}()
|
||||
containerPrefixes[containerDetails.ID] = containerIdWithPrefix
|
||||
}
|
||||
|
||||
if err = c.collectNetworkMetrics(logger, ch, containerPrefixes); err != nil {
|
||||
return fmt.Errorf("error in fetching container network statistics: %w", err)
|
||||
}
|
||||
|
||||
if len(collectErrors) > 0 {
|
||||
return fmt.Errorf("errors while fetching container statistics: %w", errors.Join(collectErrors...))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.Metric, containerDetails hcsshim.ContainerProperties, containerIdWithPrefix string) error {
|
||||
container, err := hcsshim.OpenContainer(containerDetails.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in opening container: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if container == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := container.Close(); err != nil {
|
||||
logger.Error("error in closing container",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
containerStats, err := container.Statistics()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in fetching container statistics: %w", err)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.containerAvailable,
|
||||
prometheus.CounterValue,
|
||||
1,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.usageCommitBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(containerStats.Memory.UsageCommitBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.usageCommitPeakBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(containerStats.Memory.UsageCommitPeakBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.usagePrivateWorkingSetBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(containerStats.Memory.UsagePrivateWorkingSetBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeTotal,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Processor.TotalRuntime100ns)*perftypes.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeUser,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Processor.RuntimeUser100ns)*perftypes.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeKernel,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Processor.RuntimeKernel100ns)*perftypes.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Storage.ReadCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Storage.ReadSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.writeCountNormalized,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Storage.WriteCountNormalized),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.writeSizeBytes,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Storage.WriteSizeBytes),
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectNetworkMetrics collects network metrics for containers.
|
||||
// With HNSv2, the network stats must be collected from hcsshim.HNSListEndpointRequest.
|
||||
// Network statistics from the container.Statistics() are providing data only, if HNSv1 is used.
|
||||
// Ref: https://github.com/prometheus-community/windows_exporter/pull/1218
|
||||
func (c *Collector) collectNetworkMetrics(logger *slog.Logger, ch chan<- prometheus.Metric, containerPrefixes map[string]string) error {
|
||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for containers")
|
||||
logger.Warn("Failed to collect network stats for containers")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if len(hnsEndpoints) == 0 {
|
||||
_ = level.Info(c.logger).Log("msg", "No network stats for containers to collect")
|
||||
logger.Info("No network stats for containers to collect")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, endpoint := range hnsEndpoints {
|
||||
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
|
||||
if err != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for interface "+endpoint.Id, "err", err)
|
||||
logger.Warn("Failed to collect network stats for interface "+endpoint.Id,
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
for _, containerId := range endpoint.SharedContainers {
|
||||
containerIdWithPrefix, ok := containerPrefixes[containerId]
|
||||
endpointId := strings.ToUpper(endpoint.Id)
|
||||
|
||||
if !ok {
|
||||
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for container "+containerId)
|
||||
logger.Debug("Failed to collect network stats for container " + containerId)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
endpointId := strings.ToUpper(endpoint.Id)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.bytesReceived,
|
||||
prometheus.CounterValue,
|
||||
@@ -3,8 +3,8 @@ package container_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/container"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/container"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
57
internal/collector/cpu/const.go
Normal file
57
internal/collector/cpu/const.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package cpu
|
||||
|
||||
// Processor performance counters.
|
||||
const (
|
||||
c1TimeSeconds = "% C1 Time"
|
||||
c2TimeSeconds = "% C2 Time"
|
||||
c3TimeSeconds = "% C3 Time"
|
||||
c1TransitionsTotal = "C1 Transitions/sec"
|
||||
c2TransitionsTotal = "C2 Transitions/sec"
|
||||
c3TransitionsTotal = "C3 Transitions/sec"
|
||||
clockInterruptsTotal = "Clock Interrupts/sec"
|
||||
dpcQueuedPerSecond = "DPCs Queued/sec"
|
||||
dpcTimeSeconds = "% DPC Time"
|
||||
idleBreakEventsTotal = "Idle Break Events/sec"
|
||||
idleTimeSeconds = "% Idle Time"
|
||||
interruptsTotal = "Interrupts/sec"
|
||||
interruptTimeSeconds = "% Interrupt Time"
|
||||
parkingStatus = "Parking Status"
|
||||
performanceLimitPercent = "% Performance Limit"
|
||||
priorityTimeSeconds = "% Priority Time"
|
||||
privilegedTimeSeconds = "% Privileged Time"
|
||||
privilegedUtilitySeconds = "% Privileged Utility"
|
||||
processorFrequencyMHz = "Processor Frequency"
|
||||
processorPerformance = "% Processor Performance"
|
||||
processorTimeSeconds = "% Processor Time"
|
||||
processorUtilityRate = "% Processor Utility"
|
||||
userTimeSeconds = "% User Time"
|
||||
)
|
||||
|
||||
type perflibProcessorInformation struct {
|
||||
Name string
|
||||
C1TimeSeconds float64 `perflib:"% C1 Time"`
|
||||
C2TimeSeconds float64 `perflib:"% C2 Time"`
|
||||
C3TimeSeconds float64 `perflib:"% C3 Time"`
|
||||
C1TransitionsTotal float64 `perflib:"C1 Transitions/sec"`
|
||||
C2TransitionsTotal float64 `perflib:"C2 Transitions/sec"`
|
||||
C3TransitionsTotal float64 `perflib:"C3 Transitions/sec"`
|
||||
ClockInterruptsTotal float64 `perflib:"Clock Interrupts/sec"`
|
||||
DPCsQueuedTotal float64 `perflib:"DPCs Queued/sec"`
|
||||
DPCTimeSeconds float64 `perflib:"% DPC Time"`
|
||||
IdleBreakEventsTotal float64 `perflib:"Idle Break Events/sec"`
|
||||
IdleTimeSeconds float64 `perflib:"% Idle Time"`
|
||||
InterruptsTotal float64 `perflib:"Interrupts/sec"`
|
||||
InterruptTimeSeconds float64 `perflib:"% Interrupt Time"`
|
||||
ParkingStatus float64 `perflib:"Parking Status"`
|
||||
PerformanceLimitPercent float64 `perflib:"% Performance Limit"`
|
||||
PriorityTimeSeconds float64 `perflib:"% Priority Time"`
|
||||
PrivilegedTimeSeconds float64 `perflib:"% Privileged Time"`
|
||||
PrivilegedUtilitySeconds float64 `perflib:"% Privileged Utility"`
|
||||
ProcessorFrequencyMHz float64 `perflib:"Processor Frequency"`
|
||||
ProcessorPerformance float64 `perflib:"% Processor Performance"`
|
||||
ProcessorMPerf float64 `perflib:"% Processor Performance,secondvalue"`
|
||||
ProcessorTimeSeconds float64 `perflib:"% Processor Time"`
|
||||
ProcessorUtilityRate float64 `perflib:"% Processor Utility"`
|
||||
ProcessorRTC float64 `perflib:"% Processor Utility,secondvalue"`
|
||||
UserTimeSeconds float64 `perflib:"% User Time"`
|
||||
}
|
||||
@@ -3,13 +3,16 @@
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/winversion"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -21,8 +24,13 @@ var ConfigDefaults = Config{}
|
||||
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
perfDataCollector perfdata.Collector
|
||||
|
||||
processorRTCValues map[string]utils.Counter
|
||||
processorMPerfValues map[string]utils.Counter
|
||||
|
||||
logicalProcessors *prometheus.Desc
|
||||
cStateSecondsTotal *prometheus.Desc
|
||||
timeTotal *prometheus.Desc
|
||||
interruptsTotal *prometheus.Desc
|
||||
@@ -38,7 +46,7 @@ type Collector struct {
|
||||
processorPrivilegedUtility *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -47,8 +55,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -60,22 +66,61 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
if winversion.WindowsVersionFloat > 6.05 {
|
||||
return []string{"Processor Information"}, nil
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
if utils.PDHEnabled() {
|
||||
return []string{}, nil
|
||||
}
|
||||
return []string{"Processor"}, nil
|
||||
|
||||
return []string{"Processor Information"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
if utils.PDHEnabled() {
|
||||
counters := []string{
|
||||
c1TimeSeconds,
|
||||
c2TimeSeconds,
|
||||
c3TimeSeconds,
|
||||
c1TransitionsTotal,
|
||||
c2TransitionsTotal,
|
||||
c3TransitionsTotal,
|
||||
clockInterruptsTotal,
|
||||
dpcQueuedPerSecond,
|
||||
dpcTimeSeconds,
|
||||
idleBreakEventsTotal,
|
||||
idleTimeSeconds,
|
||||
interruptsTotal,
|
||||
interruptTimeSeconds,
|
||||
parkingStatus,
|
||||
performanceLimitPercent,
|
||||
priorityTimeSeconds,
|
||||
privilegedTimeSeconds,
|
||||
privilegedUtilitySeconds,
|
||||
processorFrequencyMHz,
|
||||
processorPerformance,
|
||||
processorTimeSeconds,
|
||||
processorUtilityRate,
|
||||
userTimeSeconds,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "Processor Information", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Processor Information collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.logicalProcessors = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "logical_processor"),
|
||||
"Total number of logical processors",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
c.cStateSecondsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
@@ -100,17 +145,6 @@ func (c *Collector) Build() error {
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
|
||||
// For Windows 2008 (version 6.0) or earlier we only have the "Processor"
|
||||
// class. As of Windows 2008 R2 (version 6.1) the more detailed
|
||||
// "Processor Information" set is available (although some of the counters
|
||||
// are added in later versions, so we aren't guaranteed to get all of
|
||||
// them).
|
||||
// Value 6.05 was selected to split between Windows versions.
|
||||
if winversion.WindowsVersionFloat < 6.05 {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.cStateSecondsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
@@ -190,158 +224,63 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if winversion.WindowsVersionFloat > 6.05 {
|
||||
return c.CollectFull(ctx, ch)
|
||||
}
|
||||
|
||||
return c.CollectBasic(ctx, ch)
|
||||
}
|
||||
|
||||
type perflibProcessor struct {
|
||||
Name string
|
||||
C1Transitions float64 `perflib:"C1 Transitions/sec"`
|
||||
C2Transitions float64 `perflib:"C2 Transitions/sec"`
|
||||
C3Transitions float64 `perflib:"C3 Transitions/sec"`
|
||||
DPCRate float64 `perflib:"DPC Rate"`
|
||||
DPCsQueued float64 `perflib:"DPCs Queued/sec"`
|
||||
Interrupts float64 `perflib:"Interrupts/sec"`
|
||||
PercentC1Time float64 `perflib:"% C1 Time"`
|
||||
PercentC2Time float64 `perflib:"% C2 Time"`
|
||||
PercentC3Time float64 `perflib:"% C3 Time"`
|
||||
PercentDPCTime float64 `perflib:"% DPC Time"`
|
||||
PercentIdleTime float64 `perflib:"% Idle Time"`
|
||||
PercentInterruptTime float64 `perflib:"% Interrupt Time"`
|
||||
PercentPrivilegedTime float64 `perflib:"% Privileged Time"`
|
||||
PercentProcessorTime float64 `perflib:"% Processor Time"`
|
||||
PercentUserTime float64 `perflib:"% User Time"`
|
||||
}
|
||||
|
||||
func (c *Collector) CollectBasic(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
data := make([]perflibProcessor, 0)
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Processor"], &data, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cpu := range data {
|
||||
if strings.Contains(strings.ToLower(cpu.Name), "_total") {
|
||||
continue
|
||||
}
|
||||
core := cpu.Name
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentC1Time,
|
||||
core, "c1",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentC2Time,
|
||||
core, "c2",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentC3Time,
|
||||
core, "c3",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentIdleTime,
|
||||
core, "idle",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentInterruptTime,
|
||||
core, "interrupt",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentDPCTime,
|
||||
core, "dpc",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentPrivilegedTime,
|
||||
core, "privileged",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PercentUserTime,
|
||||
core, "user",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.interruptsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.Interrupts,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dpcsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.DPCsQueued,
|
||||
core,
|
||||
)
|
||||
}
|
||||
c.processorRTCValues = map[string]utils.Counter{}
|
||||
c.processorMPerfValues = map[string]utils.Counter{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type perflibProcessorInformation struct {
|
||||
Name string
|
||||
C1TimeSeconds float64 `perflib:"% C1 Time"`
|
||||
C2TimeSeconds float64 `perflib:"% C2 Time"`
|
||||
C3TimeSeconds float64 `perflib:"% C3 Time"`
|
||||
C1TransitionsTotal float64 `perflib:"C1 Transitions/sec"`
|
||||
C2TransitionsTotal float64 `perflib:"C2 Transitions/sec"`
|
||||
C3TransitionsTotal float64 `perflib:"C3 Transitions/sec"`
|
||||
ClockInterruptsTotal float64 `perflib:"Clock Interrupts/sec"`
|
||||
DPCsQueuedTotal float64 `perflib:"DPCs Queued/sec"`
|
||||
DPCTimeSeconds float64 `perflib:"% DPC Time"`
|
||||
IdleBreakEventsTotal float64 `perflib:"Idle Break Events/sec"`
|
||||
IdleTimeSeconds float64 `perflib:"% Idle Time"`
|
||||
InterruptsTotal float64 `perflib:"Interrupts/sec"`
|
||||
InterruptTimeSeconds float64 `perflib:"% Interrupt Time"`
|
||||
ParkingStatus float64 `perflib:"Parking Status"`
|
||||
PerformanceLimitPercent float64 `perflib:"% Performance Limit"`
|
||||
PriorityTimeSeconds float64 `perflib:"% Priority Time"`
|
||||
PrivilegedTimeSeconds float64 `perflib:"% Privileged Time"`
|
||||
PrivilegedUtilitySeconds float64 `perflib:"% Privileged Utility"`
|
||||
ProcessorFrequencyMHz float64 `perflib:"Processor Frequency"`
|
||||
ProcessorPerformance float64 `perflib:"% Processor Performance"`
|
||||
ProcessorMPerf float64 `perflib:"% Processor Performance,secondvalue"`
|
||||
ProcessorTimeSeconds float64 `perflib:"% Processor Time"`
|
||||
ProcessorUtilityRate float64 `perflib:"% Processor Utility"`
|
||||
ProcessorRTC float64 `perflib:"% Processor Utility,secondvalue"`
|
||||
UserTimeSeconds float64 `perflib:"% User Time"`
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
if utils.PDHEnabled() {
|
||||
return c.collectPDH(ch)
|
||||
}
|
||||
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
return c.collectFull(ctx, logger, ch)
|
||||
}
|
||||
|
||||
func (c *Collector) CollectFull(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collectFull(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
data := make([]perflibProcessorInformation, 0)
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Processor Information"], &data, c.logger)
|
||||
|
||||
err := v1.UnmarshalObject(ctx.PerfObjects["Processor Information"], &data, logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var coreCount float64
|
||||
|
||||
for _, cpu := range data {
|
||||
if strings.Contains(strings.ToLower(cpu.Name), "_total") {
|
||||
continue
|
||||
}
|
||||
|
||||
core := cpu.Name
|
||||
|
||||
var (
|
||||
counterProcessorRTCValues utils.Counter
|
||||
counterProcessorMPerfValues utils.Counter
|
||||
ok bool
|
||||
)
|
||||
|
||||
if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
|
||||
counterProcessorRTCValues.AddValue(uint32(cpu.ProcessorRTC))
|
||||
} else {
|
||||
counterProcessorRTCValues = utils.NewCounter(uint32(cpu.ProcessorRTC))
|
||||
}
|
||||
|
||||
c.processorRTCValues[core] = counterProcessorRTCValues
|
||||
|
||||
if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
|
||||
counterProcessorMPerfValues.AddValue(uint32(cpu.ProcessorMPerf))
|
||||
} else {
|
||||
counterProcessorMPerfValues = utils.NewCounter(uint32(cpu.ProcessorMPerf))
|
||||
}
|
||||
|
||||
c.processorMPerfValues[core] = counterProcessorMPerfValues
|
||||
|
||||
coreCount++
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
@@ -439,13 +378,13 @@ func (c *Collector) CollectFull(ctx *types.ScrapeContext, ch chan<- prometheus.M
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorMPerf,
|
||||
prometheus.CounterValue,
|
||||
cpu.ProcessorMPerf,
|
||||
counterProcessorMPerfValues.Value(),
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorRTC,
|
||||
prometheus.CounterValue,
|
||||
cpu.ProcessorRTC,
|
||||
counterProcessorRTCValues.Value(),
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -462,5 +401,173 @@ func (c *Collector) CollectFull(ctx *types.ScrapeContext, ch chan<- prometheus.M
|
||||
)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.logicalProcessors,
|
||||
prometheus.GaugeValue,
|
||||
coreCount,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
|
||||
data, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect Processor Information metrics: %w", err)
|
||||
}
|
||||
|
||||
var coreCount float64
|
||||
|
||||
for core, coreData := range data {
|
||||
coreCount++
|
||||
|
||||
var (
|
||||
counterProcessorRTCValues utils.Counter
|
||||
counterProcessorMPerfValues utils.Counter
|
||||
ok bool
|
||||
)
|
||||
|
||||
if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
|
||||
counterProcessorRTCValues.AddValue(uint32(coreData[processorUtilityRate].SecondValue))
|
||||
} else {
|
||||
counterProcessorRTCValues = utils.NewCounter(uint32(coreData[privilegedUtilitySeconds].SecondValue))
|
||||
}
|
||||
|
||||
c.processorRTCValues[core] = counterProcessorRTCValues
|
||||
|
||||
if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
|
||||
counterProcessorMPerfValues.AddValue(uint32(coreData[processorPerformance].SecondValue))
|
||||
} else {
|
||||
counterProcessorMPerfValues = utils.NewCounter(uint32(coreData[processorPerformance].SecondValue))
|
||||
}
|
||||
|
||||
c.processorMPerfValues[core] = counterProcessorMPerfValues
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[c1TimeSeconds].FirstValue,
|
||||
core, "c1",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[c2TimeSeconds].FirstValue,
|
||||
core, "c2",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[c3TimeSeconds].FirstValue,
|
||||
core, "c3",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[idleTimeSeconds].FirstValue,
|
||||
core, "idle",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[interruptTimeSeconds].FirstValue,
|
||||
core, "interrupt",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[dpcTimeSeconds].FirstValue,
|
||||
core, "dpc",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[privilegedTimeSeconds].FirstValue,
|
||||
core, "privileged",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[userTimeSeconds].FirstValue,
|
||||
core, "user",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.interruptsTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[interruptsTotal].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dpcsTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[dpcQueuedPerSecond].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clockInterruptsTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[clockInterruptsTotal].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.idleBreakEventsTotal,
|
||||
prometheus.CounterValue,
|
||||
coreData[idleBreakEventsTotal].FirstValue,
|
||||
core,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.parkingStatus,
|
||||
prometheus.GaugeValue,
|
||||
coreData[parkingStatus].FirstValue,
|
||||
core,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorFrequencyMHz,
|
||||
prometheus.GaugeValue,
|
||||
coreData[processorFrequencyMHz].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorPerformance,
|
||||
prometheus.CounterValue,
|
||||
coreData[processorPerformance].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorMPerf,
|
||||
prometheus.CounterValue,
|
||||
counterProcessorMPerfValues.Value(),
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorRTC,
|
||||
prometheus.CounterValue,
|
||||
counterProcessorRTCValues.Value(),
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorUtility,
|
||||
prometheus.CounterValue,
|
||||
coreData[processorUtilityRate].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorPrivilegedUtility,
|
||||
prometheus.CounterValue,
|
||||
coreData[privilegedUtilitySeconds].FirstValue,
|
||||
core,
|
||||
)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.logicalProcessors,
|
||||
prometheus.GaugeValue,
|
||||
coreCount,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
18
internal/collector/cpu/cpu_test.go
Normal file
18
internal/collector/cpu/cpu_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
//go:build windows
|
||||
|
||||
package cpu_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cpu"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cpu.Name, cpu.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
testutils.TestCollector(t, cpu.New, nil)
|
||||
}
|
||||
232
internal/collector/cpu_info/cpu_info.go
Normal file
232
internal/collector/cpu_info/cpu_info.go
Normal file
@@ -0,0 +1,232 @@
|
||||
//go:build windows
|
||||
|
||||
package cpu_info
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "cpu_info"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_Processor.
|
||||
type Collector struct {
|
||||
config Config
|
||||
miSession *mi.Session
|
||||
miQuery mi.Query
|
||||
|
||||
cpuInfo *prometheus.Desc
|
||||
cpuCoreCount *prometheus.Desc
|
||||
cpuEnabledCoreCount *prometheus.Desc
|
||||
cpuLogicalProcessorsCount *prometheus.Desc
|
||||
cpuThreadCount *prometheus.Desc
|
||||
cpuL2CacheSize *prometheus.Desc
|
||||
cpuL3CacheSize *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
|
||||
if miSession == nil {
|
||||
return errors.New("miSession is nil")
|
||||
}
|
||||
|
||||
miQuery, err := mi.NewQuery("SELECT Architecture, DeviceId, Description, Family, L2CacheSize, L3CacheSize, Name, ThreadCount, NumberOfCores, NumberOfEnabledCore, NumberOfLogicalProcessors FROM Win32_Processor")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
c.miQuery = miQuery
|
||||
c.miSession = miSession
|
||||
|
||||
c.cpuInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, "", Name),
|
||||
"Labelled CPU information as provided by Win32_Processor",
|
||||
[]string{
|
||||
"architecture",
|
||||
"device_id",
|
||||
"description",
|
||||
"family",
|
||||
"name",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
c.cpuThreadCount = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "thread"),
|
||||
"Number of threads per CPU",
|
||||
[]string{
|
||||
"device_id",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
c.cpuCoreCount = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "core"),
|
||||
"Number of cores per CPU",
|
||||
[]string{
|
||||
"device_id",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
c.cpuEnabledCoreCount = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "enabled_core"),
|
||||
"Number of enabled cores per CPU",
|
||||
[]string{
|
||||
"device_id",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
c.cpuLogicalProcessorsCount = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "logical_processor"),
|
||||
"Number of logical processors per CPU",
|
||||
[]string{
|
||||
"device_id",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
c.cpuL2CacheSize = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "l2_cache_size"),
|
||||
"Size of L2 cache per CPU",
|
||||
[]string{
|
||||
"device_id",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
c.cpuL3CacheSize = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "l3_cache_size"),
|
||||
"Size of L3 cache per CPU",
|
||||
[]string{
|
||||
"device_id",
|
||||
},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type miProcessor struct {
|
||||
Architecture uint32 `mi:"Architecture"`
|
||||
DeviceID string `mi:"DeviceID"`
|
||||
Description string `mi:"Description"`
|
||||
Family uint16 `mi:"Family"`
|
||||
L2CacheSize uint32 `mi:"L2CacheSize"`
|
||||
L3CacheSize uint32 `mi:"L3CacheSize"`
|
||||
Name string `mi:"Name"`
|
||||
ThreadCount uint32 `mi:"ThreadCount"`
|
||||
NumberOfCores uint32 `mi:"NumberOfCores"`
|
||||
NumberOfEnabledCore uint32 `mi:"NumberOfEnabledCore"`
|
||||
NumberOfLogicalProcessors uint32 `mi:"NumberOfLogicalProcessors"`
|
||||
|
||||
Total int
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
logger.Error("failed collecting cpu_info metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []miProcessor
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
// Some CPUs end up exposing trailing spaces for certain strings, so clean them up
|
||||
for _, processor := range dst {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cpuInfo,
|
||||
prometheus.GaugeValue,
|
||||
1.0,
|
||||
strconv.Itoa(int(processor.Architecture)),
|
||||
strings.TrimRight(processor.DeviceID, " "),
|
||||
strings.TrimRight(processor.Description, " "),
|
||||
strconv.Itoa(int(processor.Family)),
|
||||
strings.TrimRight(processor.Name, " "),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cpuCoreCount,
|
||||
prometheus.GaugeValue,
|
||||
float64(processor.NumberOfCores),
|
||||
strings.TrimRight(processor.DeviceID, " "),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cpuEnabledCoreCount,
|
||||
prometheus.GaugeValue,
|
||||
float64(processor.NumberOfEnabledCore),
|
||||
strings.TrimRight(processor.DeviceID, " "),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cpuLogicalProcessorsCount,
|
||||
prometheus.GaugeValue,
|
||||
float64(processor.NumberOfLogicalProcessors),
|
||||
strings.TrimRight(processor.DeviceID, " "),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cpuThreadCount,
|
||||
prometheus.GaugeValue,
|
||||
float64(processor.ThreadCount),
|
||||
strings.TrimRight(processor.DeviceID, " "),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cpuL2CacheSize,
|
||||
prometheus.GaugeValue,
|
||||
float64(processor.L2CacheSize),
|
||||
strings.TrimRight(processor.DeviceID, " "),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cpuL3CacheSize,
|
||||
prometheus.GaugeValue,
|
||||
float64(processor.L3CacheSize),
|
||||
strings.TrimRight(processor.DeviceID, " "),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
16
internal/collector/cpu_info/cpu_info_test.go
Normal file
16
internal/collector/cpu_info/cpu_info_test.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package cpu_info_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cpu_info"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cpu_info.Name, cpu_info.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
testutils.TestCollector(t, cpu_info.New, nil)
|
||||
}
|
||||
@@ -3,11 +3,12 @@
|
||||
package cs
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -20,14 +21,19 @@ var ConfigDefaults = Config{}
|
||||
// A Collector is a Prometheus Collector for WMI metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
// physicalMemoryBytes
|
||||
// Deprecated: Use windows_cpu_logical_processor instead
|
||||
physicalMemoryBytes *prometheus.Desc
|
||||
logicalProcessors *prometheus.Desc
|
||||
hostname *prometheus.Desc
|
||||
// logicalProcessors
|
||||
// Deprecated: Use windows_physical_memory_total_bytes instead
|
||||
logicalProcessors *prometheus.Desc
|
||||
// hostname
|
||||
// Deprecated: Use windows_os_hostname instead
|
||||
hostname *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -36,8 +42,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -49,34 +53,35 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
logger.Warn("The cs collector is deprecated and will be removed in a future release. " +
|
||||
"Logical processors has been moved to cpu_info collector. " +
|
||||
"Physical memory has been moved to memory collector. " +
|
||||
"Hostname has been moved to os collector.")
|
||||
|
||||
c.logicalProcessors = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "logical_processors"),
|
||||
"ComputerSystem.NumberOfLogicalProcessors",
|
||||
"Deprecated: Use windows_cpu_logical_processor instead",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.physicalMemoryBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "physical_memory_bytes"),
|
||||
"ComputerSystem.TotalPhysicalMemory",
|
||||
"Deprecated: Use windows_physical_memory_total_bytes instead",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.hostname = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "hostname"),
|
||||
"Labelled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain",
|
||||
"Deprecated: Use windows_os_hostname instead",
|
||||
[]string{
|
||||
"hostname",
|
||||
"domain",
|
||||
@@ -84,16 +89,23 @@ func (c *Collector) Build() error {
|
||||
},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
if err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting cs metrics", "err", err)
|
||||
logger.Error("failed collecting cs metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -123,10 +135,12 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
domain, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSDomain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fqdn, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSFullyQualified)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -3,8 +3,8 @@ package cs_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/cs"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cs"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
101
internal/collector/dfsr/const.go
Normal file
101
internal/collector/dfsr/const.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package dfsr
|
||||
|
||||
const (
|
||||
// Connection Perflib: "DFS Replication Service Connections".
|
||||
bytesReceivedTotal = "Total Bytes Received"
|
||||
|
||||
// Folder Perflib: "DFS Replicated Folder".
|
||||
bandwidthSavingsUsingDFSReplicationTotal = "Bandwidth Savings Using DFS Replication"
|
||||
compressedSizeOfFilesReceivedTotal = "Compressed Size of Files Received"
|
||||
conflictBytesCleanedUpTotal = "Conflict Bytes Cleaned Up"
|
||||
conflictBytesGeneratedTotal = "Conflict Bytes Generated"
|
||||
conflictFilesCleanedUpTotal = "Conflict Files Cleaned Up"
|
||||
conflictFilesGeneratedTotal = "Conflict Files Generated"
|
||||
conflictFolderCleanupsCompletedTotal = "Conflict folder Cleanups Completed"
|
||||
conflictSpaceInUse = "Conflict Space In Use"
|
||||
deletedSpaceInUse = "Deleted Space In Use"
|
||||
deletedBytesCleanedUpTotal = "Deleted Bytes Cleaned Up"
|
||||
deletedBytesGeneratedTotal = "Deleted Bytes Generated"
|
||||
deletedFilesCleanedUpTotal = "Deleted Files Cleaned Up"
|
||||
deletedFilesGeneratedTotal = "Deleted Files Generated"
|
||||
fileInstallsRetriedTotal = "File Installs Retried"
|
||||
fileInstallsSucceededTotal = "File Installs Succeeded"
|
||||
filesReceivedTotal = "Total Files Received"
|
||||
rdcBytesReceivedTotal = "RDC Bytes Received"
|
||||
rdcCompressedSizeOfFilesReceivedTotal = "RDC Compressed Size of Files Received"
|
||||
rdcNumberOfFilesReceivedTotal = "RDC Number of Files Received"
|
||||
rdcSizeOfFilesReceivedTotal = "RDC Size of Files Received"
|
||||
sizeOfFilesReceivedTotal = "Size of Files Received"
|
||||
stagingSpaceInUse = "Staging Space In Use"
|
||||
stagingBytesCleanedUpTotal = "Staging Bytes Cleaned Up"
|
||||
stagingBytesGeneratedTotal = "Staging Bytes Generated"
|
||||
stagingFilesCleanedUpTotal = "Staging Files Cleaned Up"
|
||||
stagingFilesGeneratedTotal = "Staging Files Generated"
|
||||
updatesDroppedTotal = "Updates Dropped"
|
||||
|
||||
// Volume Perflib: "DFS Replication Service Volumes".
|
||||
databaseCommitsTotal = "Database Commits"
|
||||
databaseLookupsTotal = "Database Lookups"
|
||||
usnJournalRecordsReadTotal = "USN Journal Records Read"
|
||||
usnJournalRecordsAcceptedTotal = "USN Journal Records Accepted"
|
||||
usnJournalUnreadPercentage = "USN Journal Records Unread Percentage"
|
||||
)
|
||||
|
||||
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections".
|
||||
type PerflibDFSRConnection struct {
|
||||
Name string
|
||||
|
||||
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
|
||||
BytesReceivedTotal float64 `perflib:"Total Bytes Received"`
|
||||
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
|
||||
FilesReceivedTotal float64 `perflib:"Total Files Received"`
|
||||
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
|
||||
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
|
||||
RDCNumberOfFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
|
||||
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
|
||||
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
|
||||
}
|
||||
|
||||
// perflibDFSRFolder Perflib: "DFS Replicated Folder".
|
||||
type perflibDFSRFolder struct {
|
||||
Name string
|
||||
|
||||
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
|
||||
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
|
||||
ConflictBytesCleanedUpTotal float64 `perflib:"Conflict Bytes Cleaned Up"`
|
||||
ConflictBytesGeneratedTotal float64 `perflib:"Conflict Bytes Generated"`
|
||||
ConflictFilesCleanedUpTotal float64 `perflib:"Conflict Files Cleaned Up"`
|
||||
ConflictFilesGeneratedTotal float64 `perflib:"Conflict Files Generated"`
|
||||
ConflictFolderCleanupsCompletedTotal float64 `perflib:"Conflict folder Cleanups Completed"`
|
||||
ConflictSpaceInUse float64 `perflib:"Conflict Space In Use"`
|
||||
DeletedSpaceInUse float64 `perflib:"Deleted Space In Use"`
|
||||
DeletedBytesCleanedUpTotal float64 `perflib:"Deleted Bytes Cleaned Up"`
|
||||
DeletedBytesGeneratedTotal float64 `perflib:"Deleted Bytes Generated"`
|
||||
DeletedFilesCleanedUpTotal float64 `perflib:"Deleted Files Cleaned Up"`
|
||||
DeletedFilesGeneratedTotal float64 `perflib:"Deleted Files Generated"`
|
||||
FileInstallsRetriedTotal float64 `perflib:"File Installs Retried"`
|
||||
FileInstallsSucceededTotal float64 `perflib:"File Installs Succeeded"`
|
||||
FilesReceivedTotal float64 `perflib:"Total Files Received"`
|
||||
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
|
||||
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
|
||||
RDCNumberOfFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
|
||||
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
|
||||
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
|
||||
StagingSpaceInUse float64 `perflib:"Staging Space In Use"`
|
||||
StagingBytesCleanedUpTotal float64 `perflib:"Staging Bytes Cleaned Up"`
|
||||
StagingBytesGeneratedTotal float64 `perflib:"Staging Bytes Generated"`
|
||||
StagingFilesCleanedUpTotal float64 `perflib:"Staging Files Cleaned Up"`
|
||||
StagingFilesGeneratedTotal float64 `perflib:"Staging Files Generated"`
|
||||
UpdatesDroppedTotal float64 `perflib:"Updates Dropped"`
|
||||
}
|
||||
|
||||
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes".
|
||||
type perflibDFSRVolume struct {
|
||||
Name string
|
||||
|
||||
DatabaseCommitsTotal float64 `perflib:"Database Commits"`
|
||||
DatabaseLookupsTotal float64 `perflib:"Database Lookups"`
|
||||
USNJournalRecordsReadTotal float64 `perflib:"USN Journal Records Read"`
|
||||
USNJournalRecordsAcceptedTotal float64 `perflib:"USN Journal Records Accepted"`
|
||||
USNJournalUnreadPercentage float64 `perflib:"USN Journal Records Unread Percentage"`
|
||||
}
|
||||
@@ -3,14 +3,18 @@
|
||||
package dfsr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -27,7 +31,10 @@ var ConfigDefaults = Config{
|
||||
// Collector contains the metric and state data of the DFSR collectors.
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
perfDataCollectorConnection perfdata.Collector
|
||||
perfDataCollectorFolder perfdata.Collector
|
||||
perfDataCollectorVolume perfdata.Collector
|
||||
|
||||
// connection source
|
||||
connectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
|
||||
@@ -37,17 +44,17 @@ type Collector struct {
|
||||
connectionRDCBytesReceivedTotal *prometheus.Desc
|
||||
connectionRDCCompressedSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
connectionRDCSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
connectionRDCNumberofFilesReceivedTotal *prometheus.Desc
|
||||
connectionRDCNumberOfFilesReceivedTotal *prometheus.Desc
|
||||
connectionSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
|
||||
// folder source
|
||||
folderBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
|
||||
folderCompressedSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderConflictBytesCleanedupTotal *prometheus.Desc
|
||||
folderConflictBytesCleanedUpTotal *prometheus.Desc
|
||||
folderConflictBytesGeneratedTotal *prometheus.Desc
|
||||
folderConflictFilesCleanedUpTotal *prometheus.Desc
|
||||
folderConflictFilesGeneratedTotal *prometheus.Desc
|
||||
folderConflictfolderCleanupsCompletedTotal *prometheus.Desc
|
||||
folderConflictFolderCleanupsCompletedTotal *prometheus.Desc
|
||||
folderConflictSpaceInUse *prometheus.Desc
|
||||
folderDeletedSpaceInUse *prometheus.Desc
|
||||
folderDeletedBytesCleanedUpTotal *prometheus.Desc
|
||||
@@ -59,7 +66,7 @@ type Collector struct {
|
||||
folderFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCBytesReceivedTotal *prometheus.Desc
|
||||
folderRDCCompressedSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCNumberofFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCNumberOfFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderStagingSpaceInUse *prometheus.Desc
|
||||
@@ -80,13 +87,14 @@ type Collector struct {
|
||||
dfsrChildCollectors []dfsrCollectorFunc
|
||||
}
|
||||
|
||||
type dfsrCollectorFunc func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error
|
||||
type dfsrCollectorFunc func(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error
|
||||
|
||||
// Map Perflib sources to DFSR Collector names
|
||||
// e.g, volume -> DFS Replication Service Volumes.
|
||||
func dfsrGetPerfObjectName(collector string) string {
|
||||
prefix := "DFS "
|
||||
suffix := ""
|
||||
|
||||
switch collector {
|
||||
case "connection":
|
||||
suffix = "Replication Connections"
|
||||
@@ -95,10 +103,11 @@ func dfsrGetPerfObjectName(collector string) string {
|
||||
case "volume":
|
||||
suffix = "Replication Service Volumes"
|
||||
}
|
||||
|
||||
return prefix + suffix
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -111,8 +120,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -120,10 +127,11 @@ func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
c.config.CollectorsEnabled = make([]string, 0)
|
||||
|
||||
var collectorsEnabled string
|
||||
|
||||
app.Flag("collectors.dfsr.sources-enabled", "Comma-separated list of DFSR Perflib sources to use.").
|
||||
app.Flag("collector.dfsr.sources-enabled", "Comma-separated list of DFSR Perflib sources to use.").
|
||||
Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
@@ -139,11 +147,11 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
if utils.PDHEnabled() {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||
expandedChildCollectors := slices.Compact(c.config.CollectorsEnabled)
|
||||
perflibDependencies := make([]string, 0, len(expandedChildCollectors))
|
||||
@@ -155,12 +163,90 @@ func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
return perflibDependencies, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
_ = level.Info(c.logger).Log("msg", "dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
logger.Info("dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
|
||||
//nolint:nestif
|
||||
if utils.PDHEnabled() {
|
||||
var err error
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "connection") {
|
||||
counters := []string{
|
||||
bandwidthSavingsUsingDFSReplicationTotal,
|
||||
bytesReceivedTotal,
|
||||
compressedSizeOfFilesReceivedTotal,
|
||||
filesReceivedTotal,
|
||||
rdcBytesReceivedTotal,
|
||||
rdcCompressedSizeOfFilesReceivedTotal,
|
||||
rdcNumberOfFilesReceivedTotal,
|
||||
rdcSizeOfFilesReceivedTotal,
|
||||
sizeOfFilesReceivedTotal,
|
||||
}
|
||||
|
||||
c.perfDataCollectorConnection, err = perfdata.NewCollector(perfdata.V1, "DFS Replication Connections", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DFS Replication Connections collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "folder") {
|
||||
counters := []string{
|
||||
bandwidthSavingsUsingDFSReplicationTotal,
|
||||
compressedSizeOfFilesReceivedTotal,
|
||||
conflictBytesCleanedUpTotal,
|
||||
conflictBytesGeneratedTotal,
|
||||
conflictFilesCleanedUpTotal,
|
||||
conflictFilesGeneratedTotal,
|
||||
conflictFolderCleanupsCompletedTotal,
|
||||
conflictSpaceInUse,
|
||||
deletedSpaceInUse,
|
||||
deletedBytesCleanedUpTotal,
|
||||
deletedBytesGeneratedTotal,
|
||||
deletedFilesCleanedUpTotal,
|
||||
deletedFilesGeneratedTotal,
|
||||
fileInstallsRetriedTotal,
|
||||
fileInstallsSucceededTotal,
|
||||
filesReceivedTotal,
|
||||
rdcBytesReceivedTotal,
|
||||
rdcCompressedSizeOfFilesReceivedTotal,
|
||||
rdcNumberOfFilesReceivedTotal,
|
||||
rdcSizeOfFilesReceivedTotal,
|
||||
sizeOfFilesReceivedTotal,
|
||||
stagingSpaceInUse,
|
||||
stagingBytesCleanedUpTotal,
|
||||
stagingBytesGeneratedTotal,
|
||||
stagingFilesCleanedUpTotal,
|
||||
stagingFilesGeneratedTotal,
|
||||
updatesDroppedTotal,
|
||||
}
|
||||
|
||||
c.perfDataCollectorFolder, err = perfdata.NewCollector(perfdata.V1, "DFS Replicated Folders", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DFS Replicated Folders collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "volume") {
|
||||
counters := []string{
|
||||
databaseCommitsTotal,
|
||||
databaseLookupsTotal,
|
||||
usnJournalRecordsReadTotal,
|
||||
usnJournalRecordsAcceptedTotal,
|
||||
usnJournalUnreadPercentage,
|
||||
}
|
||||
|
||||
c.perfDataCollectorVolume, err = perfdata.NewCollector(perfdata.V1, "DFS Replication Service Volumes", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DFS Replication Service Volumes collector: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// connection
|
||||
c.connectionBandwidthSavingsUsingDFSReplicationTotal = prometheus.NewDesc(
|
||||
@@ -205,7 +291,7 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.connectionRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
|
||||
c.connectionRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_received_files_total"),
|
||||
"Total number of files received using remote differential compression",
|
||||
[]string{"name"},
|
||||
@@ -241,7 +327,7 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.folderConflictBytesCleanedupTotal = prometheus.NewDesc(
|
||||
c.folderConflictBytesCleanedUpTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_cleaned_up_bytes_total"),
|
||||
"Total size of conflict loser files and folders deleted from the Conflict and Deleted folder, in bytes",
|
||||
[]string{"name"},
|
||||
@@ -269,7 +355,7 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.folderConflictfolderCleanupsCompletedTotal = prometheus.NewDesc(
|
||||
c.folderConflictFolderCleanupsCompletedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_folder_cleanups_total"),
|
||||
"Number of deletions of conflict loser files and folders in the Conflict and Deleted",
|
||||
[]string{"name"},
|
||||
@@ -353,7 +439,7 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.folderRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
|
||||
c.folderRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_received_files_total"),
|
||||
"Total number of files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
@@ -463,6 +549,7 @@ func (c *Collector) Build() error {
|
||||
// for use in Collector.Collect().
|
||||
func (c *Collector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCollectorFunc {
|
||||
var dfsrCollectors []dfsrCollectorFunc
|
||||
|
||||
for _, collector := range enabledCollectors {
|
||||
switch collector {
|
||||
case "connection":
|
||||
@@ -479,34 +566,26 @@ func (c *Collector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCol
|
||||
|
||||
// Collect implements the Collector interface.
|
||||
// Sends metric values for each metric to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
if utils.PDHEnabled() {
|
||||
return c.collectPDH(ch)
|
||||
}
|
||||
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
for _, fn := range c.dfsrChildCollectors {
|
||||
err := fn(ctx, ch)
|
||||
err := fn(ctx, logger, ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections".
|
||||
type PerflibDFSRConnection struct {
|
||||
Name string
|
||||
|
||||
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
|
||||
BytesReceivedTotal float64 `perflib:"Total Bytes Received"`
|
||||
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
|
||||
FilesReceivedTotal float64 `perflib:"Total Files Received"`
|
||||
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
|
||||
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
|
||||
RDCNumberofFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
|
||||
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
|
||||
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectConnection(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collectConnection(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var dst []PerflibDFSRConnection
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Connections"], &dst, c.logger); err != nil {
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["DFS Replication Connections"], &dst, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -561,9 +640,9 @@ func (c *Collector) collectConnection(ctx *types.ScrapeContext, ch chan<- promet
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCNumberofFilesReceivedTotal,
|
||||
c.connectionRDCNumberOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.RDCNumberofFilesReceivedTotal,
|
||||
connection.RDCNumberOfFilesReceivedTotal,
|
||||
connection.Name,
|
||||
)
|
||||
|
||||
@@ -574,45 +653,14 @@ func (c *Collector) collectConnection(ctx *types.ScrapeContext, ch chan<- promet
|
||||
connection.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// perflibDFSRFolder Perflib: "DFS Replicated Folder".
|
||||
type perflibDFSRFolder struct {
|
||||
Name string
|
||||
|
||||
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
|
||||
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
|
||||
ConflictBytesCleanedupTotal float64 `perflib:"Conflict Bytes Cleaned Up"`
|
||||
ConflictBytesGeneratedTotal float64 `perflib:"Conflict Bytes Generated"`
|
||||
ConflictFilesCleanedUpTotal float64 `perflib:"Conflict Files Cleaned Up"`
|
||||
ConflictFilesGeneratedTotal float64 `perflib:"Conflict Files Generated"`
|
||||
ConflictFolderCleanupsCompletedTotal float64 `perflib:"Conflict folder Cleanups Completed"`
|
||||
ConflictSpaceInUse float64 `perflib:"Conflict Space In Use"`
|
||||
DeletedSpaceInUse float64 `perflib:"Deleted Space In Use"`
|
||||
DeletedBytesCleanedUpTotal float64 `perflib:"Deleted Bytes Cleaned Up"`
|
||||
DeletedBytesGeneratedTotal float64 `perflib:"Deleted Bytes Generated"`
|
||||
DeletedFilesCleanedUpTotal float64 `perflib:"Deleted Files Cleaned Up"`
|
||||
DeletedFilesGeneratedTotal float64 `perflib:"Deleted Files Generated"`
|
||||
FileInstallsRetriedTotal float64 `perflib:"File Installs Retried"`
|
||||
FileInstallsSucceededTotal float64 `perflib:"File Installs Succeeded"`
|
||||
FilesReceivedTotal float64 `perflib:"Total Files Received"`
|
||||
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
|
||||
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
|
||||
RDCNumberofFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
|
||||
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
|
||||
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
|
||||
StagingSpaceInUse float64 `perflib:"Staging Space In Use"`
|
||||
StagingBytesCleanedUpTotal float64 `perflib:"Staging Bytes Cleaned Up"`
|
||||
StagingBytesGeneratedTotal float64 `perflib:"Staging Bytes Generated"`
|
||||
StagingFilesCleanedUpTotal float64 `perflib:"Staging Files Cleaned Up"`
|
||||
StagingFilesGeneratedTotal float64 `perflib:"Staging Files Generated"`
|
||||
UpdatesDroppedTotal float64 `perflib:"Updates Dropped"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collectFolder(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var dst []perflibDFSRFolder
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replicated Folders"], &dst, c.logger); err != nil {
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["DFS Replicated Folders"], &dst, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -632,9 +680,9 @@ func (c *Collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictBytesCleanedupTotal,
|
||||
c.folderConflictBytesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.ConflictBytesCleanedupTotal,
|
||||
folder.ConflictBytesCleanedUpTotal,
|
||||
folder.Name,
|
||||
)
|
||||
|
||||
@@ -660,7 +708,7 @@ func (c *Collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictfolderCleanupsCompletedTotal,
|
||||
c.folderConflictFolderCleanupsCompletedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.ConflictFolderCleanupsCompletedTotal,
|
||||
folder.Name,
|
||||
@@ -744,9 +792,9 @@ func (c *Collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCNumberofFilesReceivedTotal,
|
||||
c.folderRDCNumberOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.RDCNumberofFilesReceivedTotal,
|
||||
folder.RDCNumberOfFilesReceivedTotal,
|
||||
folder.Name,
|
||||
)
|
||||
|
||||
@@ -806,23 +854,14 @@ func (c *Collector) collectFolder(ctx *types.ScrapeContext, ch chan<- prometheus
|
||||
folder.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes".
|
||||
type perflibDFSRVolume struct {
|
||||
Name string
|
||||
|
||||
DatabaseCommitsTotal float64 `perflib:"Database Commits"`
|
||||
DatabaseLookupsTotal float64 `perflib:"Database Lookups"`
|
||||
USNJournalRecordsReadTotal float64 `perflib:"USN Journal Records Read"`
|
||||
USNJournalRecordsAcceptedTotal float64 `perflib:"USN Journal Records Accepted"`
|
||||
USNJournalUnreadPercentage float64 `perflib:"USN Journal Records Unread Percentage"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectVolume(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collectVolume(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var dst []perflibDFSRVolume
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Service volumes"], &dst, c.logger); err != nil {
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["DFS Replication Service Volumes"], &dst, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -862,5 +901,356 @@ func (c *Collector) collectVolume(ctx *types.ScrapeContext, ch chan<- prometheus
|
||||
volume.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
|
||||
errs := make([]error, 0, 3)
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "connection") {
|
||||
errs = append(errs, c.collectPDHConnection(ch))
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "folder") {
|
||||
errs = append(errs, c.collectPDHFolder(ch))
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "volume") {
|
||||
errs = append(errs, c.collectPDHVolume(ch))
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHConnection(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorConnection.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DFS Replication Connections metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for DFS Replication Connections returned empty result set")
|
||||
}
|
||||
|
||||
for name, connection := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionBandwidthSavingsUsingDFSReplicationTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[bandwidthSavingsUsingDFSReplicationTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionBytesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[bytesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[compressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[filesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCBytesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[rdcBytesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[rdcCompressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[rdcSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCNumberOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[rdcNumberOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection[sizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHFolder(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorFolder.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DFS Replicated Folders metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for DFS Replicated Folders returned empty result set")
|
||||
}
|
||||
|
||||
for name, folder := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderBandwidthSavingsUsingDFSReplicationTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[bandwidthSavingsUsingDFSReplicationTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[compressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictBytesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[conflictBytesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictBytesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[conflictBytesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictFilesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[conflictFilesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictFilesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[conflictFilesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictFolderCleanupsCompletedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[conflictFolderCleanupsCompletedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictSpaceInUse,
|
||||
prometheus.GaugeValue,
|
||||
folder[conflictSpaceInUse].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedSpaceInUse,
|
||||
prometheus.GaugeValue,
|
||||
folder[deletedSpaceInUse].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedBytesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[deletedBytesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedBytesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[deletedBytesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedFilesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[deletedFilesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedFilesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[deletedFilesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderFileInstallsRetriedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[fileInstallsRetriedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderFileInstallsSucceededTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[fileInstallsSucceededTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[filesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCBytesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[rdcBytesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[rdcCompressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCNumberOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[rdcNumberOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[rdcSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[sizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingSpaceInUse,
|
||||
prometheus.GaugeValue,
|
||||
folder[stagingSpaceInUse].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingBytesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[stagingBytesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingBytesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[stagingBytesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingFilesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[stagingFilesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingFilesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[stagingFilesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderUpdatesDroppedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder[updatesDroppedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHVolume(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorVolume.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DFS Replication Volumes metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for DFS Replication Volumes returned empty result set")
|
||||
}
|
||||
|
||||
for name, volume := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeDatabaseLookupsTotal,
|
||||
prometheus.CounterValue,
|
||||
volume[databaseLookupsTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeDatabaseCommitsTotal,
|
||||
prometheus.CounterValue,
|
||||
volume[databaseCommitsTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeUSNJournalRecordsAcceptedTotal,
|
||||
prometheus.CounterValue,
|
||||
volume[usnJournalRecordsAcceptedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeUSNJournalRecordsReadTotal,
|
||||
prometheus.CounterValue,
|
||||
volume[usnJournalRecordsReadTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeUSNJournalUnreadPercentage,
|
||||
prometheus.GaugeValue,
|
||||
volume[usnJournalUnreadPercentage].FirstValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package dfsr_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dfsr"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/dfsr"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
60
internal/collector/dhcp/const.go
Normal file
60
internal/collector/dhcp/const.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package dhcp
|
||||
|
||||
const (
|
||||
acksTotal = "Acks/sec"
|
||||
activeQueueLength = "Active Queue Length"
|
||||
conflictCheckQueueLength = "Conflict Check Queue Length"
|
||||
declinesTotal = "Declines/sec"
|
||||
deniedDueToMatch = "Denied due to match."
|
||||
deniedDueToNonMatch = "Denied due to match."
|
||||
discoversTotal = "Discovers/sec"
|
||||
duplicatesDroppedTotal = "Duplicates Dropped/sec"
|
||||
failoverBndAckReceivedTotal = "Failover: BndAck received/sec."
|
||||
failoverBndAckSentTotal = "Failover: BndAck sent/sec."
|
||||
failoverBndUpdDropped = "Failover: BndUpd Dropped."
|
||||
failoverBndUpdPendingOutboundQueue = "Failover: BndUpd pending in outbound queue."
|
||||
failoverBndUpdReceivedTotal = "Failover: BndUpd received/sec."
|
||||
failoverBndUpdSentTotal = "Failover: BndUpd sent/sec."
|
||||
failoverTransitionsCommunicationInterruptedState = "Failover: Transitions to COMMUNICATION-INTERRUPTED state."
|
||||
failoverTransitionsPartnerDownState = "Failover: Transitions to PARTNER-DOWN state."
|
||||
failoverTransitionsRecoverState = "Failover: Transitions to RECOVER state."
|
||||
informsTotal = "Informs/sec"
|
||||
nacksTotal = "Nacks/sec"
|
||||
offerQueueLength = "Offer Queue Length"
|
||||
offersTotal = "Offers/sec"
|
||||
packetsExpiredTotal = "Packets Expired/sec"
|
||||
packetsReceivedTotal = "Packets Received/sec"
|
||||
releasesTotal = "Releases/sec"
|
||||
requestsTotal = "Requests/sec"
|
||||
)
|
||||
|
||||
// represents perflib metrics from the DHCP Server class.
|
||||
// While the name of a number of perflib metrics would indicate a rate is being returned (E.G. Packets Received/sec),
|
||||
// perflib instead returns a counter, hence the "Total" suffix in some of the variable names.
|
||||
type dhcpPerf struct {
|
||||
AcksTotal float64 `perflib:"Acks/sec"`
|
||||
ActiveQueueLength float64 `perflib:"Active Queue Length"`
|
||||
ConflictCheckQueueLength float64 `perflib:"Conflict Check Queue Length"`
|
||||
DeclinesTotal float64 `perflib:"Declines/sec"`
|
||||
DeniedDueToMatch float64 `perflib:"Denied due to match."`
|
||||
DeniedDueToNonMatch float64 `perflib:"Denied due to match."`
|
||||
DiscoversTotal float64 `perflib:"Discovers/sec"`
|
||||
DuplicatesDroppedTotal float64 `perflib:"Duplicates Dropped/sec"`
|
||||
FailoverBndAckReceivedTotal float64 `perflib:"Failover: BndAck received/sec."`
|
||||
FailoverBndAckSentTotal float64 `perflib:"Failover: BndAck sent/sec."`
|
||||
FailoverBndUpdDropped float64 `perflib:"Failover: BndUpd Dropped."`
|
||||
FailoverBndUpdPendingOutboundQueue float64 `perflib:"Failover: BndUpd pending in outbound queue."`
|
||||
FailoverBndUpdReceivedTotal float64 `perflib:"Failover: BndUpd received/sec."`
|
||||
FailoverBndUpdSentTotal float64 `perflib:"Failover: BndUpd sent/sec."`
|
||||
FailoverTransitionsCommunicationInterruptedState float64 `perflib:"Failover: Transitions to COMMUNICATION-INTERRUPTED state."`
|
||||
FailoverTransitionsPartnerDownState float64 `perflib:"Failover: Transitions to PARTNER-DOWN state."`
|
||||
FailoverTransitionsRecoverState float64 `perflib:"Failover: Transitions to RECOVER state."`
|
||||
InformsTotal float64 `perflib:"Informs/sec"`
|
||||
NacksTotal float64 `perflib:"Nacks/sec"`
|
||||
OfferQueueLength float64 `perflib:"Offer Queue Length"`
|
||||
OffersTotal float64 `perflib:"Offers/sec"`
|
||||
PacketsExpiredTotal float64 `perflib:"Packets Expired/sec"`
|
||||
PacketsReceivedTotal float64 `perflib:"Packets Received/sec"`
|
||||
ReleasesTotal float64 `perflib:"Releases/sec"`
|
||||
RequestsTotal float64 `perflib:"Requests/sec"`
|
||||
}
|
||||
@@ -3,10 +3,17 @@
|
||||
package dhcp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -19,7 +26,8 @@ var ConfigDefaults = Config{}
|
||||
// A Collector is a Prometheus Collector perflib DHCP metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
perfDataCollector perfdata.Collector
|
||||
|
||||
acksTotal *prometheus.Desc
|
||||
activeQueueLength *prometheus.Desc
|
||||
@@ -29,12 +37,12 @@ type Collector struct {
|
||||
deniedDueToNonMatch *prometheus.Desc
|
||||
discoversTotal *prometheus.Desc
|
||||
duplicatesDroppedTotal *prometheus.Desc
|
||||
failoverBndackReceivedTotal *prometheus.Desc
|
||||
failoverBndackSentTotal *prometheus.Desc
|
||||
failoverBndupdDropped *prometheus.Desc
|
||||
failoverBndupdPendingOutboundQueue *prometheus.Desc
|
||||
failoverBndupdReceivedTotal *prometheus.Desc
|
||||
failoverBndupdSentTotal *prometheus.Desc
|
||||
failoverBndAckReceivedTotal *prometheus.Desc
|
||||
failoverBndAckSentTotal *prometheus.Desc
|
||||
failoverBndUpdDropped *prometheus.Desc
|
||||
failoverBndUpdPendingOutboundQueue *prometheus.Desc
|
||||
failoverBndUpdReceivedTotal *prometheus.Desc
|
||||
failoverBndUpdSentTotal *prometheus.Desc
|
||||
failoverTransitionsCommunicationInterruptedState *prometheus.Desc
|
||||
failoverTransitionsPartnerDownState *prometheus.Desc
|
||||
failoverTransitionsRecoverState *prometheus.Desc
|
||||
@@ -48,7 +56,7 @@ type Collector struct {
|
||||
requestsTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -57,8 +65,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -70,19 +76,56 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
if utils.PDHEnabled() {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
return []string{"DHCP Server"}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
if utils.PDHEnabled() {
|
||||
counters := []string{
|
||||
acksTotal,
|
||||
activeQueueLength,
|
||||
conflictCheckQueueLength,
|
||||
declinesTotal,
|
||||
deniedDueToMatch,
|
||||
deniedDueToNonMatch,
|
||||
discoversTotal,
|
||||
duplicatesDroppedTotal,
|
||||
failoverBndAckReceivedTotal,
|
||||
failoverBndAckSentTotal,
|
||||
failoverBndUpdDropped,
|
||||
failoverBndUpdPendingOutboundQueue,
|
||||
failoverBndUpdReceivedTotal,
|
||||
failoverBndUpdSentTotal,
|
||||
failoverTransitionsCommunicationInterruptedState,
|
||||
failoverTransitionsPartnerDownState,
|
||||
failoverTransitionsRecoverState,
|
||||
informsTotal,
|
||||
nacksTotal,
|
||||
offerQueueLength,
|
||||
offersTotal,
|
||||
packetsExpiredTotal,
|
||||
packetsReceivedTotal,
|
||||
releasesTotal,
|
||||
requestsTotal,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "DHCP Server", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DHCP Server collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.packetsReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "packets_received_total"),
|
||||
"Total number of packets received by the DHCP server (PacketsReceivedTotal)",
|
||||
@@ -179,31 +222,31 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdSentTotal = prometheus.NewDesc(
|
||||
c.failoverBndUpdSentTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_sent_total"),
|
||||
"Number of DHCP fail over Binding Update messages sent (FailoverBndupdSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdReceivedTotal = prometheus.NewDesc(
|
||||
c.failoverBndUpdReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_received_total"),
|
||||
"Number of DHCP fail over Binding Update messages received (FailoverBndupdReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndackSentTotal = prometheus.NewDesc(
|
||||
c.failoverBndAckSentTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_sent_total"),
|
||||
"Number of DHCP fail over Binding Ack messages sent (FailoverBndackSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndackReceivedTotal = prometheus.NewDesc(
|
||||
c.failoverBndAckReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_received_total"),
|
||||
"Number of DHCP fail over Binding Ack messages received (FailoverBndackReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdPendingOutboundQueue = prometheus.NewDesc(
|
||||
c.failoverBndUpdPendingOutboundQueue = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_pending_in_outbound_queue"),
|
||||
"Number of pending outbound DHCP fail over Binding Update messages (FailoverBndupdPendingOutboundQueue)",
|
||||
nil,
|
||||
@@ -227,49 +270,30 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdDropped = prometheus.NewDesc(
|
||||
c.failoverBndUpdDropped = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_dropped_total"),
|
||||
"Total number of DHCP fail over Binding Updates dropped (FailoverBndupdDropped)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// represents perflib metrics from the DHCP Server class.
|
||||
// While the name of a number of perflib metrics would indicate a rate is being returned (E.G. Packets Received/sec),
|
||||
// perflib instead returns a counter, hence the "Total" suffix in some of the variable names.
|
||||
type dhcpPerf struct {
|
||||
PacketsReceivedTotal float64 `perflib:"Packets Received/sec"`
|
||||
DuplicatesDroppedTotal float64 `perflib:"Duplicates Dropped/sec"`
|
||||
PacketsExpiredTotal float64 `perflib:"Packets Expired/sec"`
|
||||
ActiveQueueLength float64 `perflib:"Active Queue Length"`
|
||||
ConflictCheckQueueLength float64 `perflib:"Conflict Check Queue Length"`
|
||||
DiscoversTotal float64 `perflib:"Discovers/sec"`
|
||||
OffersTotal float64 `perflib:"Offers/sec"`
|
||||
RequestsTotal float64 `perflib:"Requests/sec"`
|
||||
InformsTotal float64 `perflib:"Informs/sec"`
|
||||
AcksTotal float64 `perflib:"Acks/sec"`
|
||||
NacksTotal float64 `perflib:"Nacks/sec"`
|
||||
DeclinesTotal float64 `perflib:"Declines/sec"`
|
||||
ReleasesTotal float64 `perflib:"Releases/sec"`
|
||||
DeniedDueToMatch float64 `perflib:"Denied due to match."`
|
||||
DeniedDueToNonMatch float64 `perflib:"Denied due to match."`
|
||||
OfferQueueLength float64 `perflib:"Offer Queue Length"`
|
||||
FailoverBndupdSentTotal float64 `perflib:"Failover: BndUpd sent/sec."`
|
||||
FailoverBndupdReceivedTotal float64 `perflib:"Failover: BndUpd received/sec."`
|
||||
FailoverBndackSentTotal float64 `perflib:"Failover: BndAck sent/sec."`
|
||||
FailoverBndackReceivedTotal float64 `perflib:"Failover: BndAck received/sec."`
|
||||
FailoverBndupdPendingOutboundQueue float64 `perflib:"Failover: BndUpd pending in outbound queue."`
|
||||
FailoverTransitionsCommunicationinterruptedState float64 `perflib:"Failover: Transitions to COMMUNICATION-INTERRUPTED state."`
|
||||
FailoverTransitionsPartnerdownState float64 `perflib:"Failover: Transitions to PARTNER-DOWN state."`
|
||||
FailoverTransitionsRecoverState float64 `perflib:"Failover: Transitions to RECOVER state."`
|
||||
FailoverBndupdDropped float64 `perflib:"Failover: BndUpd Dropped."`
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
if utils.PDHEnabled() {
|
||||
return c.collectPDH(ch)
|
||||
}
|
||||
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
return c.collect(ctx, logger, ch)
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var dhcpPerfs []dhcpPerf
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DHCP Server"], &dhcpPerfs, c.logger); err != nil {
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["DHCP Server"], &dhcpPerfs, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -370,45 +394,45 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdSentTotal,
|
||||
c.failoverBndUpdSentTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndupdSentTotal,
|
||||
dhcpPerfs[0].FailoverBndUpdSentTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdReceivedTotal,
|
||||
c.failoverBndUpdReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndupdReceivedTotal,
|
||||
dhcpPerfs[0].FailoverBndUpdReceivedTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndackSentTotal,
|
||||
c.failoverBndAckSentTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndackSentTotal,
|
||||
dhcpPerfs[0].FailoverBndAckSentTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndackReceivedTotal,
|
||||
c.failoverBndAckReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndackReceivedTotal,
|
||||
dhcpPerfs[0].FailoverBndAckReceivedTotal,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdPendingOutboundQueue,
|
||||
c.failoverBndUpdPendingOutboundQueue,
|
||||
prometheus.GaugeValue,
|
||||
dhcpPerfs[0].FailoverBndupdPendingOutboundQueue,
|
||||
dhcpPerfs[0].FailoverBndUpdPendingOutboundQueue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsCommunicationInterruptedState,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverTransitionsCommunicationinterruptedState,
|
||||
dhcpPerfs[0].FailoverTransitionsCommunicationInterruptedState,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsPartnerDownState,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverTransitionsPartnerdownState,
|
||||
dhcpPerfs[0].FailoverTransitionsPartnerDownState,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -418,9 +442,173 @@ func (c *Collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdDropped,
|
||||
c.failoverBndUpdDropped,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndupdDropped,
|
||||
dhcpPerfs[0].FailoverBndUpdDropped,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DHCP Server metrics: %w", err)
|
||||
}
|
||||
|
||||
data, ok := perfData[perftypes.EmptyInstance]
|
||||
if !ok {
|
||||
return errors.New("perflib query for DHCP Server returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.packetsReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
data[packetsReceivedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.duplicatesDroppedTotal,
|
||||
prometheus.CounterValue,
|
||||
data[duplicatesDroppedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.packetsExpiredTotal,
|
||||
prometheus.CounterValue,
|
||||
data[packetsExpiredTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[activeQueueLength].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.conflictCheckQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[conflictCheckQueueLength].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.discoversTotal,
|
||||
prometheus.CounterValue,
|
||||
data[discoversTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.offersTotal,
|
||||
prometheus.CounterValue,
|
||||
data[offersTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestsTotal,
|
||||
prometheus.CounterValue,
|
||||
data[requestsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.informsTotal,
|
||||
prometheus.CounterValue,
|
||||
data[informsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.acksTotal,
|
||||
prometheus.CounterValue,
|
||||
data[acksTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.nACKsTotal,
|
||||
prometheus.CounterValue,
|
||||
data[nacksTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.declinesTotal,
|
||||
prometheus.CounterValue,
|
||||
data[declinesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.releasesTotal,
|
||||
prometheus.CounterValue,
|
||||
data[releasesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.offerQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[offerQueueLength].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.deniedDueToMatch,
|
||||
prometheus.CounterValue,
|
||||
data[deniedDueToMatch].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.deniedDueToNonMatch,
|
||||
prometheus.CounterValue,
|
||||
data[deniedDueToNonMatch].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndUpdSentTotal,
|
||||
prometheus.CounterValue,
|
||||
data[failoverBndUpdSentTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndUpdReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
data[failoverBndUpdReceivedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndAckSentTotal,
|
||||
prometheus.CounterValue,
|
||||
data[failoverBndAckSentTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndAckReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
data[failoverBndAckReceivedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndUpdPendingOutboundQueue,
|
||||
prometheus.GaugeValue,
|
||||
data[failoverBndUpdPendingOutboundQueue].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsCommunicationInterruptedState,
|
||||
prometheus.CounterValue,
|
||||
data[failoverTransitionsCommunicationInterruptedState].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsPartnerDownState,
|
||||
prometheus.CounterValue,
|
||||
data[failoverTransitionsPartnerDownState].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsRecoverState,
|
||||
prometheus.CounterValue,
|
||||
data[failoverTransitionsRecoverState].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndUpdDropped,
|
||||
prometheus.CounterValue,
|
||||
data[failoverBndUpdDropped].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
@@ -3,8 +3,8 @@ package dhcp_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dhcp"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/dhcp"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
@@ -4,20 +4,17 @@ package diskdrive
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
Name = "diskdrive"
|
||||
win32DiskQuery = "SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive"
|
||||
)
|
||||
const Name = "diskdrive"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
@@ -25,8 +22,9 @@ var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive.
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
config Config
|
||||
miSession *mi.Session
|
||||
miQuery mi.Query
|
||||
|
||||
availability *prometheus.Desc
|
||||
diskInfo *prometheus.Desc
|
||||
@@ -35,7 +33,7 @@ type Collector struct {
|
||||
status *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -44,8 +42,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -57,19 +53,27 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
|
||||
if miSession == nil {
|
||||
return errors.New("miSession is nil")
|
||||
}
|
||||
|
||||
miQuery, err := mi.NewQuery("SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
c.miQuery = miQuery
|
||||
c.miSession = miSession
|
||||
|
||||
c.diskInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||
"General drive information",
|
||||
@@ -110,14 +114,14 @@ func (c *Collector) Build() error {
|
||||
}
|
||||
|
||||
type win32_DiskDrive struct {
|
||||
DeviceID string
|
||||
Model string
|
||||
Size uint64
|
||||
Name string
|
||||
Caption string
|
||||
Partitions uint32
|
||||
Status string
|
||||
Availability uint16
|
||||
DeviceID string `mi:"DeviceID"`
|
||||
Model string `mi:"Model"`
|
||||
Size uint64 `mi:"Size"`
|
||||
Name string `mi:"Name"`
|
||||
Caption string `mi:"Caption"`
|
||||
Partitions uint32 `mi:"Partitions"`
|
||||
Status string `mi:"Status"`
|
||||
Availability uint16 `mi:"Availability"`
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -162,20 +166,25 @@ var (
|
||||
)
|
||||
|
||||
// Collect sends the metric values for each metric to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting disk_drive_info metrics", "err", err)
|
||||
logger.Error("failed collecting disk_drive_info metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []win32_DiskDrive
|
||||
|
||||
if err := wmi.Query(win32DiskQuery, &dst); err != nil {
|
||||
return err
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
if len(dst) == 0 {
|
||||
return errors.New("WMI query returned empty result set")
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package diskdrive_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/diskdrive"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/diskdrive"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
92
internal/collector/dns/const.go
Normal file
92
internal/collector/dns/const.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package dns
|
||||
|
||||
const (
|
||||
_ = "% User Time"
|
||||
_ = "176"
|
||||
_ = "Async Fast Reads/sec"
|
||||
axfrRequestReceived = "AXFR Request Received"
|
||||
axfrRequestSent = "AXFR Request Sent"
|
||||
axfrResponseReceived = "AXFR Response Received"
|
||||
axfrSuccessReceived = "AXFR Success Received"
|
||||
axfrSuccessSent = "AXFR Success Sent"
|
||||
cachingMemory = "Caching Memory"
|
||||
_ = "Data Flush Pages/sec"
|
||||
_ = "Data Flushes/sec"
|
||||
databaseNodeMemory = "Database Node Memory"
|
||||
dynamicUpdateNoOperation = "Dynamic Update NoOperation"
|
||||
_ = "Dynamic Update NoOperation/sec"
|
||||
dynamicUpdateQueued = "Dynamic Update Queued"
|
||||
_ = "Dynamic Update Received"
|
||||
_ = "Dynamic Update Received/sec"
|
||||
dynamicUpdateRejected = "Dynamic Update Rejected"
|
||||
dynamicUpdateTimeOuts = "Dynamic Update TimeOuts"
|
||||
dynamicUpdateWrittenToDatabase = "Dynamic Update Written to Database"
|
||||
_ = "Dynamic Update Written to Database/sec"
|
||||
_ = "Enumerations Server/sec"
|
||||
_ = "Fast Read Not Possibles/sec"
|
||||
_ = "Fast Read Resource Misses/sec"
|
||||
ixfrRequestReceived = "IXFR Request Received"
|
||||
ixfrRequestSent = "IXFR Request Sent"
|
||||
ixfrResponseReceived = "IXFR Response Received"
|
||||
_ = "IXFR Success Received"
|
||||
ixfrSuccessSent = "IXFR Success Sent"
|
||||
ixfrTCPSuccessReceived = "IXFR TCP Success Received"
|
||||
ixfrUDPSuccessReceived = "IXFR UDP Success Received"
|
||||
_ = "Lazy Write Flushes/sec"
|
||||
_ = "Lazy Write Pages/sec"
|
||||
_ = "Level 2 TLB Fills/sec"
|
||||
nbStatMemory = "Nbstat Memory"
|
||||
notifyReceived = "Notify Received"
|
||||
notifySent = "Notify Sent"
|
||||
_ = "Query Dropped Bad Socket"
|
||||
_ = "Query Dropped Bad Socket/sec"
|
||||
_ = "Query Dropped By Policy"
|
||||
_ = "Query Dropped By Policy/sec"
|
||||
_ = "Query Dropped By Response Rate Limiting"
|
||||
_ = "Query Dropped By Response Rate Limiting/sec"
|
||||
_ = "Query Dropped Send"
|
||||
_ = "Query Dropped Send/sec"
|
||||
_ = "Query Dropped Total"
|
||||
_ = "Query Dropped Total/sec"
|
||||
recordFlowMemory = "Record Flow Memory"
|
||||
recursiveQueries = "Recursive Queries"
|
||||
_ = "Recursive Queries/sec"
|
||||
recursiveQueryFailure = "Recursive Query Failure"
|
||||
_ = "Recursive Query Failure/sec"
|
||||
_ = "Recursive Send TimeOuts"
|
||||
recursiveSendTimeOuts = "Recursive TimeOut/sec"
|
||||
_ = "Responses Suppressed"
|
||||
_ = "Responses Suppressed/sec"
|
||||
secureUpdateFailure = "Secure Update Failure"
|
||||
secureUpdateReceived = "Secure Update Received"
|
||||
_ = "Secure Update Received/sec"
|
||||
tcpMessageMemory = "TCP Message Memory"
|
||||
tcpQueryReceived = "TCP Query Received"
|
||||
_ = "TCP Query Received/sec"
|
||||
tcpResponseSent = "TCP Response Sent"
|
||||
_ = "TCP Response Sent/sec"
|
||||
_ = "Total Query Received"
|
||||
_ = "Total Query Received/sec"
|
||||
_ = "Total Remote Inflight Queries"
|
||||
_ = "Total Response Sent"
|
||||
_ = "Total Response Sent/sec"
|
||||
udpMessageMemory = "UDP Message Memory"
|
||||
udpQueryReceived = "UDP Query Received"
|
||||
_ = "UDP Query Received/sec"
|
||||
udpResponseSent = "UDP Response Sent"
|
||||
_ = "UDP Response Sent/sec"
|
||||
unmatchedResponsesReceived = "Unmatched Responses Received"
|
||||
_ = "Virtual Bytes"
|
||||
winsLookupReceived = "WINS Lookup Received"
|
||||
_ = "WINS Lookup Received/sec"
|
||||
winsResponseSent = "WINS Response Sent"
|
||||
_ = "WINS Response Sent/sec"
|
||||
winsReverseLookupReceived = "WINS Reverse Lookup Received"
|
||||
_ = "WINS Reverse Lookup Received/sec"
|
||||
winsReverseResponseSent = "WINS Reverse Response Sent"
|
||||
_ = "WINS Reverse Response Sent/sec"
|
||||
zoneTransferFailure = "Zone Transfer Failure"
|
||||
zoneTransferSOARequestSent = "Zone Transfer Request Received"
|
||||
_ = "Zone Transfer SOA Request Sent"
|
||||
_ = "Zone Transfer Success"
|
||||
)
|
||||
@@ -4,12 +4,14 @@ package dns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata/perftypes"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
@@ -22,7 +24,8 @@ var ConfigDefaults = Config{}
|
||||
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
logger log.Logger
|
||||
|
||||
perfDataCollector perfdata.Collector
|
||||
|
||||
dynamicUpdatesFailures *prometheus.Desc
|
||||
dynamicUpdatesQueued *prometheus.Desc
|
||||
@@ -48,7 +51,7 @@ type Collector struct {
|
||||
zoneTransferSuccessSent *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(logger log.Logger, config *Config) *Collector {
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
@@ -57,8 +60,6 @@ func New(logger log.Logger, config *Config) *Collector {
|
||||
config: *config,
|
||||
}
|
||||
|
||||
c.SetLogger(logger)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -70,19 +71,65 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) SetLogger(logger log.Logger) {
|
||||
c.logger = log.With(logger, "collector", Name)
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter() ([]string, error) {
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
counters := []string{
|
||||
axfrRequestReceived,
|
||||
axfrRequestSent,
|
||||
axfrResponseReceived,
|
||||
axfrSuccessReceived,
|
||||
axfrSuccessSent,
|
||||
cachingMemory,
|
||||
databaseNodeMemory,
|
||||
dynamicUpdateNoOperation,
|
||||
dynamicUpdateQueued,
|
||||
dynamicUpdateRejected,
|
||||
dynamicUpdateTimeOuts,
|
||||
dynamicUpdateWrittenToDatabase,
|
||||
ixfrRequestReceived,
|
||||
ixfrRequestSent,
|
||||
ixfrResponseReceived,
|
||||
ixfrSuccessSent,
|
||||
ixfrTCPSuccessReceived,
|
||||
ixfrUDPSuccessReceived,
|
||||
nbStatMemory,
|
||||
notifyReceived,
|
||||
notifySent,
|
||||
recordFlowMemory,
|
||||
recursiveQueries,
|
||||
recursiveQueryFailure,
|
||||
recursiveSendTimeOuts,
|
||||
secureUpdateFailure,
|
||||
secureUpdateReceived,
|
||||
tcpMessageMemory,
|
||||
tcpQueryReceived,
|
||||
tcpResponseSent,
|
||||
udpMessageMemory,
|
||||
udpQueryReceived,
|
||||
udpResponseSent,
|
||||
unmatchedResponsesReceived,
|
||||
winsLookupReceived,
|
||||
winsResponseSent,
|
||||
winsReverseLookupReceived,
|
||||
winsReverseResponseSent,
|
||||
zoneTransferFailure,
|
||||
zoneTransferSOARequestSent,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector(perfdata.V1, "DNS", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DNS collector: %w", err)
|
||||
}
|
||||
|
||||
c.zoneTransferRequestsReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) received by the master DNS server",
|
||||
@@ -215,138 +262,86 @@ func (c *Collector) Build() error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if err := c.collect(ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", "failed collecting dns metrics", "err", err)
|
||||
return err
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, _ *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DNS metrics: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_PerfRawData_DNS_DNS docs:
|
||||
// - https://msdn.microsoft.com/en-us/library/ms803992.aspx?f=255&MSPPError=-2147217396
|
||||
// - https://technet.microsoft.com/en-us/library/cc977686.aspx
|
||||
type Win32_PerfRawData_DNS_DNS struct {
|
||||
AXFRRequestReceived uint32
|
||||
AXFRRequestSent uint32
|
||||
AXFRResponseReceived uint32
|
||||
AXFRSuccessReceived uint32
|
||||
AXFRSuccessSent uint32
|
||||
CachingMemory uint32
|
||||
DatabaseNodeMemory uint32
|
||||
DynamicUpdateNoOperation uint32
|
||||
DynamicUpdateQueued uint32
|
||||
DynamicUpdateRejected uint32
|
||||
DynamicUpdateTimeOuts uint32
|
||||
DynamicUpdateWrittentoDatabase uint32
|
||||
IXFRRequestReceived uint32
|
||||
IXFRRequestSent uint32
|
||||
IXFRResponseReceived uint32
|
||||
IXFRSuccessSent uint32
|
||||
IXFRTCPSuccessReceived uint32
|
||||
IXFRUDPSuccessReceived uint32
|
||||
NbstatMemory uint32
|
||||
NotifyReceived uint32
|
||||
NotifySent uint32
|
||||
RecordFlowMemory uint32
|
||||
RecursiveQueries uint32
|
||||
RecursiveQueryFailure uint32
|
||||
RecursiveSendTimeOuts uint32
|
||||
SecureUpdateFailure uint32
|
||||
SecureUpdateReceived uint32
|
||||
TCPMessageMemory uint32
|
||||
TCPQueryReceived uint32
|
||||
TCPResponseSent uint32
|
||||
UDPMessageMemory uint32
|
||||
UDPQueryReceived uint32
|
||||
UDPResponseSent uint32
|
||||
UnmatchedResponsesReceived uint32
|
||||
WINSLookupReceived uint32
|
||||
WINSResponseSent uint32
|
||||
WINSReverseLookupReceived uint32
|
||||
WINSReverseResponseSent uint32
|
||||
ZoneTransferFailure uint32
|
||||
ZoneTransferSOARequestSent uint32
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_DNS_DNS
|
||||
q := wmi.QueryAll(&dst, c.logger)
|
||||
if err := wmi.Query(q, &dst); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(dst) == 0 {
|
||||
return errors.New("WMI query returned empty result set")
|
||||
data, ok := perfData[perftypes.EmptyInstance]
|
||||
if !ok {
|
||||
return errors.New("perflib query for DNS returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRRequestReceived),
|
||||
data[axfrRequestReceived].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRRequestReceived),
|
||||
data[ixfrRequestReceived].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRRequestSent),
|
||||
data[axfrRequestSent].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRRequestSent),
|
||||
data[ixfrRequestSent].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].ZoneTransferSOARequestSent),
|
||||
data[zoneTransferSOARequestSent].FirstValue,
|
||||
"soa",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRResponseReceived),
|
||||
data[axfrResponseReceived].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRResponseReceived),
|
||||
data[ixfrResponseReceived].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRSuccessReceived),
|
||||
data[axfrSuccessReceived].FirstValue,
|
||||
"full",
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRTCPSuccessReceived),
|
||||
data[ixfrTCPSuccessReceived].FirstValue,
|
||||
"incremental",
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRTCPSuccessReceived),
|
||||
data[ixfrTCPSuccessReceived].FirstValue,
|
||||
"incremental",
|
||||
"udp",
|
||||
)
|
||||
@@ -354,183 +349,183 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRSuccessSent),
|
||||
data[axfrSuccessSent].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRSuccessSent),
|
||||
data[ixfrSuccessSent].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].ZoneTransferFailure),
|
||||
data[zoneTransferFailure].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].CachingMemory),
|
||||
data[cachingMemory].FirstValue,
|
||||
"caching",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].DatabaseNodeMemory),
|
||||
data[databaseNodeMemory].FirstValue,
|
||||
"database_node",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].NbstatMemory),
|
||||
data[nbStatMemory].FirstValue,
|
||||
"nbstat",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].RecordFlowMemory),
|
||||
data[recordFlowMemory].FirstValue,
|
||||
"record_flow",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].TCPMessageMemory),
|
||||
data[tcpMessageMemory].FirstValue,
|
||||
"tcp_message",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].UDPMessageMemory),
|
||||
data[udpMessageMemory].FirstValue,
|
||||
"udp_message",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateNoOperation),
|
||||
data[dynamicUpdateNoOperation].FirstValue,
|
||||
"noop",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateWrittentoDatabase),
|
||||
data[dynamicUpdateWrittenToDatabase].FirstValue,
|
||||
"written",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesQueued,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].DynamicUpdateQueued),
|
||||
data[dynamicUpdateQueued].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateRejected),
|
||||
data[dynamicUpdateRejected].FirstValue,
|
||||
"rejected",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateTimeOuts),
|
||||
data[dynamicUpdateTimeOuts].FirstValue,
|
||||
"timeout",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.notifyReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].NotifyReceived),
|
||||
data[notifyReceived].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.notifySent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].NotifySent),
|
||||
data[notifySent].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQueries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].RecursiveQueries),
|
||||
data[recursiveQueries].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQueryFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].RecursiveQueryFailure),
|
||||
data[recursiveQueryFailure].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQuerySendTimeouts,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].RecursiveSendTimeOuts),
|
||||
data[recursiveSendTimeOuts].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.queries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].TCPQueryReceived),
|
||||
data[tcpQueryReceived].FirstValue,
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.queries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].UDPQueryReceived),
|
||||
data[udpQueryReceived].FirstValue,
|
||||
"udp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.responses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].TCPResponseSent),
|
||||
data[tcpResponseSent].FirstValue,
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.responses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].UDPResponseSent),
|
||||
data[udpResponseSent].FirstValue,
|
||||
"udp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.unmatchedResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].UnmatchedResponsesReceived),
|
||||
data[unmatchedResponsesReceived].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsQueries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSLookupReceived),
|
||||
data[winsLookupReceived].FirstValue,
|
||||
"forward",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsQueries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSReverseLookupReceived),
|
||||
data[winsReverseLookupReceived].FirstValue,
|
||||
"reverse",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsResponses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSResponseSent),
|
||||
data[winsResponseSent].FirstValue,
|
||||
"forward",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsResponses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSReverseResponseSent),
|
||||
data[winsReverseResponseSent].FirstValue,
|
||||
"reverse",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.secureUpdateFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].SecureUpdateFailure),
|
||||
data[secureUpdateFailure].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.secureUpdateReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].SecureUpdateReceived),
|
||||
data[secureUpdateReceived].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
@@ -3,8 +3,8 @@ package dns_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/dns"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/dns"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
352
internal/collector/exchange/exchange.go
Normal file
352
internal/collector/exchange/exchange.go
Normal file
@@ -0,0 +1,352 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "exchange"
|
||||
|
||||
const (
|
||||
adAccessProcesses = "ADAccessProcesses"
|
||||
transportQueues = "TransportQueues"
|
||||
httpProxy = "HttpProxy"
|
||||
activeSync = "ActiveSync"
|
||||
availabilityService = "AvailabilityService"
|
||||
outlookWebAccess = "OutlookWebAccess"
|
||||
autoDiscover = "Autodiscover"
|
||||
workloadManagement = "WorkloadManagement"
|
||||
rpcClientAccess = "RpcClientAccess"
|
||||
mapiHttpEmsmdb = "MapiHttpEmsmdb"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
}
|
||||
|
||||
var ConfigDefaults = Config{
|
||||
CollectorsEnabled: []string{
|
||||
adAccessProcesses,
|
||||
transportQueues,
|
||||
httpProxy,
|
||||
activeSync,
|
||||
availabilityService,
|
||||
outlookWebAccess,
|
||||
autoDiscover,
|
||||
workloadManagement,
|
||||
rpcClientAccess,
|
||||
mapiHttpEmsmdb,
|
||||
},
|
||||
}
|
||||
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollectorADAccessProcesses perfdata.Collector
|
||||
perfDataCollectorTransportQueues perfdata.Collector
|
||||
perfDataCollectorHttpProxy perfdata.Collector
|
||||
perfDataCollectorActiveSync perfdata.Collector
|
||||
perfDataCollectorAvailabilityService perfdata.Collector
|
||||
perfDataCollectorOWA perfdata.Collector
|
||||
perfDataCollectorAutoDiscover perfdata.Collector
|
||||
perfDataCollectorWorkloadManagementWorkloads perfdata.Collector
|
||||
perfDataCollectorRpcClientAccess perfdata.Collector
|
||||
perfDataCollectorMapiHttpEmsmdb perfdata.Collector
|
||||
|
||||
activeMailboxDeliveryQueueLength *prometheus.Desc
|
||||
activeSyncRequestsPerSec *prometheus.Desc
|
||||
activeTasks *prometheus.Desc
|
||||
activeUserCount *prometheus.Desc
|
||||
activeUserCountMapiHttpEmsMDB *prometheus.Desc
|
||||
autoDiscoverRequestsPerSec *prometheus.Desc
|
||||
availabilityRequestsSec *prometheus.Desc
|
||||
averageAuthenticationLatency *prometheus.Desc
|
||||
averageCASProcessingLatency *prometheus.Desc
|
||||
completedTasks *prometheus.Desc
|
||||
connectionCount *prometheus.Desc
|
||||
currentUniqueUsers *prometheus.Desc
|
||||
externalActiveRemoteDeliveryQueueLength *prometheus.Desc
|
||||
externalLargestDeliveryQueueLength *prometheus.Desc
|
||||
internalActiveRemoteDeliveryQueueLength *prometheus.Desc
|
||||
internalLargestDeliveryQueueLength *prometheus.Desc
|
||||
isActive *prometheus.Desc
|
||||
ldapReadTime *prometheus.Desc
|
||||
ldapSearchTime *prometheus.Desc
|
||||
ldapTimeoutErrorsPerSec *prometheus.Desc
|
||||
ldapWriteTime *prometheus.Desc
|
||||
longRunningLDAPOperationsPerMin *prometheus.Desc
|
||||
mailboxServerLocatorAverageLatency *prometheus.Desc
|
||||
mailboxServerProxyFailureRate *prometheus.Desc
|
||||
outstandingProxyRequests *prometheus.Desc
|
||||
owaRequestsPerSec *prometheus.Desc
|
||||
pingCommandsPending *prometheus.Desc
|
||||
poisonQueueLength *prometheus.Desc
|
||||
proxyRequestsPerSec *prometheus.Desc
|
||||
queuedTasks *prometheus.Desc
|
||||
retryMailboxDeliveryQueueLength *prometheus.Desc
|
||||
rpcAveragedLatency *prometheus.Desc
|
||||
rpcOperationsPerSec *prometheus.Desc
|
||||
rpcRequests *prometheus.Desc
|
||||
syncCommandsPerSec *prometheus.Desc
|
||||
unreachableQueueLength *prometheus.Desc
|
||||
userCount *prometheus.Desc
|
||||
yieldedTasks *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
if config.CollectorsEnabled == nil {
|
||||
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
c.config.CollectorsEnabled = make([]string, 0)
|
||||
|
||||
var listAllCollectors bool
|
||||
|
||||
var collectorsEnabled string
|
||||
|
||||
app.Flag(
|
||||
"collector.exchange.list",
|
||||
"List the collectors along with their perflib object name/ids",
|
||||
).BoolVar(&listAllCollectors)
|
||||
|
||||
app.Flag(
|
||||
"collector.exchange.enabled",
|
||||
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||
).Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
|
||||
|
||||
app.PreAction(func(*kingpin.ParseContext) error {
|
||||
if listAllCollectors {
|
||||
collectorDesc := map[string]string{
|
||||
adAccessProcesses: "[19108] MSExchange ADAccess Processes",
|
||||
transportQueues: "[20524] MSExchangeTransport Queues",
|
||||
httpProxy: "[36934] MSExchange HttpProxy",
|
||||
activeSync: "[25138] MSExchange ActiveSync",
|
||||
availabilityService: "[24914] MSExchange Availability Service",
|
||||
outlookWebAccess: "[24618] MSExchange OWA",
|
||||
autoDiscover: "[29240] MSExchange Autodiscover",
|
||||
workloadManagement: "[19430] MSExchange WorkloadManagement Workloads",
|
||||
rpcClientAccess: "[29336] MSExchange RpcClientAccess",
|
||||
mapiHttpEmsmdb: "[26463] MSExchange MapiHttp Emsmdb",
|
||||
}
|
||||
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString(fmt.Sprintf("%-32s %-32s\n", "Collector Name", "[PerfID] Perflib Object"))
|
||||
|
||||
for _, cname := range ConfigDefaults.CollectorsEnabled {
|
||||
sb.WriteString(fmt.Sprintf("%-32s %-32s\n", cname, collectorDesc[cname]))
|
||||
}
|
||||
|
||||
app.UsageTemplate(sb.String()).Usage(nil)
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
c.config.CollectorsEnabled = strings.Split(collectorsEnabled, ",")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
if utils.PDHEnabled() {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
return []string{
|
||||
"MSExchange ADAccess Processes",
|
||||
"MSExchangeTransport Queues",
|
||||
"MSExchange HttpProxy",
|
||||
"MSExchange ActiveSync",
|
||||
"MSExchange Availability Service",
|
||||
"MSExchange OWA",
|
||||
"MSExchangeAutodiscover",
|
||||
"MSExchange WorkloadManagement Workloads",
|
||||
"MSExchange RpcClientAccess",
|
||||
"MSExchange MapiHttp Emsmdb",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
if utils.PDHEnabled() {
|
||||
collectorFuncs := map[string]func() error{
|
||||
adAccessProcesses: c.buildADAccessProcesses,
|
||||
transportQueues: c.buildTransportQueues,
|
||||
httpProxy: c.buildHTTPProxy,
|
||||
activeSync: c.buildActiveSync,
|
||||
availabilityService: c.buildAvailabilityService,
|
||||
outlookWebAccess: c.buildOWA,
|
||||
autoDiscover: c.buildAutoDiscover,
|
||||
workloadManagement: c.buildWorkloadManagementWorkloads,
|
||||
rpcClientAccess: c.buildRPC,
|
||||
mapiHttpEmsmdb: c.buildMapiHttpEmsmdb,
|
||||
}
|
||||
|
||||
for _, collectorName := range c.config.CollectorsEnabled {
|
||||
if err := collectorFuncs[collectorName](); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// desc creates a new prometheus description
|
||||
desc := func(metricName string, description string, labels ...string) *prometheus.Desc {
|
||||
return prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, metricName),
|
||||
description,
|
||||
labels,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
c.rpcAveragedLatency = desc("rpc_avg_latency_sec", "The latency (sec) averaged for the past 1024 packets")
|
||||
c.rpcRequests = desc("rpc_requests", "Number of client requests currently being processed by the RPC Client Access service")
|
||||
c.activeUserCount = desc("rpc_active_user_count", "Number of unique users that have shown some kind of activity in the last 2 minutes")
|
||||
c.connectionCount = desc("rpc_connection_count", "Total number of client connections maintained")
|
||||
c.rpcOperationsPerSec = desc("rpc_operations_total", "The rate at which RPC operations occur")
|
||||
c.userCount = desc("rpc_user_count", "Number of users")
|
||||
c.ldapReadTime = desc("ldap_read_time_sec", "Time (sec) to send an LDAP read request and receive a response", "name")
|
||||
c.ldapSearchTime = desc("ldap_search_time_sec", "Time (sec) to send an LDAP search request and receive a response", "name")
|
||||
c.ldapWriteTime = desc("ldap_write_time_sec", "Time (sec) to send an LDAP Add/Modify/Delete request and receive a response", "name")
|
||||
c.ldapTimeoutErrorsPerSec = desc("ldap_timeout_errors_total", "Total number of LDAP timeout errors", "name")
|
||||
c.longRunningLDAPOperationsPerMin = desc("ldap_long_running_ops_per_sec", "Long Running LDAP operations per second", "name")
|
||||
c.externalActiveRemoteDeliveryQueueLength = desc("transport_queues_external_active_remote_delivery", "External Active Remote Delivery Queue length", "name")
|
||||
c.internalActiveRemoteDeliveryQueueLength = desc("transport_queues_internal_active_remote_delivery", "Internal Active Remote Delivery Queue length", "name")
|
||||
c.activeMailboxDeliveryQueueLength = desc("transport_queues_active_mailbox_delivery", "Active Mailbox Delivery Queue length", "name")
|
||||
c.retryMailboxDeliveryQueueLength = desc("transport_queues_retry_mailbox_delivery", "Retry Mailbox Delivery Queue length", "name")
|
||||
c.unreachableQueueLength = desc("transport_queues_unreachable", "Unreachable Queue length", "name")
|
||||
c.externalLargestDeliveryQueueLength = desc("transport_queues_external_largest_delivery", "External Largest Delivery Queue length", "name")
|
||||
c.internalLargestDeliveryQueueLength = desc("transport_queues_internal_largest_delivery", "Internal Largest Delivery Queue length", "name")
|
||||
c.poisonQueueLength = desc("transport_queues_poison", "Poison Queue length", "name")
|
||||
c.mailboxServerLocatorAverageLatency = desc("http_proxy_mailbox_server_locator_avg_latency_sec", "Average latency (sec) of MailboxServerLocator web service calls", "name")
|
||||
c.averageAuthenticationLatency = desc("http_proxy_avg_auth_latency", "Average time spent authenticating CAS requests over the last 200 samples", "name")
|
||||
c.outstandingProxyRequests = desc("http_proxy_outstanding_proxy_requests", "Number of concurrent outstanding proxy requests", "name")
|
||||
c.proxyRequestsPerSec = desc("http_proxy_requests_total", "Number of proxy requests processed each second", "name")
|
||||
c.availabilityRequestsSec = desc("avail_service_requests_per_sec", "Number of requests serviced per second")
|
||||
c.currentUniqueUsers = desc("owa_current_unique_users", "Number of unique users currently logged on to Outlook Web App")
|
||||
c.owaRequestsPerSec = desc("owa_requests_total", "Number of requests handled by Outlook Web App per second")
|
||||
c.autoDiscoverRequestsPerSec = desc("autodiscover_requests_total", "Number of autodiscover service requests processed each second")
|
||||
c.activeTasks = desc("workload_active_tasks", "Number of active tasks currently running in the background for workload management", "name")
|
||||
c.completedTasks = desc("workload_completed_tasks", "Number of workload management tasks that have been completed", "name")
|
||||
c.queuedTasks = desc("workload_queued_tasks", "Number of workload management tasks that are currently queued up waiting to be processed", "name")
|
||||
c.yieldedTasks = desc("workload_yielded_tasks", "The total number of tasks that have been yielded by a workload", "name")
|
||||
c.isActive = desc("workload_is_active", "Active indicates whether the workload is in an active (1) or paused (0) state", "name")
|
||||
c.activeSyncRequestsPerSec = desc("activesync_requests_total", "Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load")
|
||||
c.averageCASProcessingLatency = desc("http_proxy_avg_cas_processing_latency_sec", "Average latency (sec) of CAS processing time over the last 200 reqs", "name")
|
||||
c.mailboxServerProxyFailureRate = desc("http_proxy_mailbox_proxy_failure_rate", "% of failures between this CAS and MBX servers over the last 200 samples", "name")
|
||||
c.pingCommandsPending = desc("activesync_ping_cmds_pending", "Number of ping commands currently pending in the queue")
|
||||
c.syncCommandsPerSec = desc("activesync_sync_cmds_total", "Number of sync commands processed per second. Clients use this command to synchronize items within a folder")
|
||||
c.activeUserCountMapiHttpEmsMDB = desc("mapihttp_emsmdb_active_user_count", "Number of unique outlook users that have shown some kind of activity in the last 2 minutes")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect collects exchange metrics and sends them to prometheus.
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
if utils.PDHEnabled() {
|
||||
return c.collectPDH(ch)
|
||||
}
|
||||
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
collectorFuncs := map[string]func(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error{
|
||||
adAccessProcesses: c.collectADAccessProcesses,
|
||||
transportQueues: c.collectTransportQueues,
|
||||
httpProxy: c.collectHTTPProxy,
|
||||
activeSync: c.collectActiveSync,
|
||||
availabilityService: c.collectAvailabilityService,
|
||||
outlookWebAccess: c.collectOWA,
|
||||
autoDiscover: c.collectAutoDiscover,
|
||||
workloadManagement: c.collectWorkloadManagementWorkloads,
|
||||
rpcClientAccess: c.collectRPC,
|
||||
mapiHttpEmsmdb: c.collectMapiHttpEmsmdb,
|
||||
}
|
||||
|
||||
for _, collectorName := range c.config.CollectorsEnabled {
|
||||
if err := collectorFuncs[collectorName](ctx, logger, ch); err != nil {
|
||||
logger.Error("Error in "+collectorName,
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect collects exchange metrics and sends them to prometheus.
|
||||
func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
|
||||
collectorFuncs := map[string]func(ch chan<- prometheus.Metric) error{
|
||||
adAccessProcesses: c.collectPDHADAccessProcesses,
|
||||
transportQueues: c.collectPDHTransportQueues,
|
||||
httpProxy: c.collectPDHHTTPProxy,
|
||||
activeSync: c.collectPDHActiveSync,
|
||||
availabilityService: c.collectPDHAvailabilityService,
|
||||
outlookWebAccess: c.collectPDHOWA,
|
||||
autoDiscover: c.collectPDHAutoDiscover,
|
||||
workloadManagement: c.collectPDHWorkloadManagementWorkloads,
|
||||
rpcClientAccess: c.collectPDHRPC,
|
||||
mapiHttpEmsmdb: c.collectPDHMapiHttpEmsmdb,
|
||||
}
|
||||
|
||||
errs := make([]error, len(c.config.CollectorsEnabled))
|
||||
|
||||
for i, collectorName := range c.config.CollectorsEnabled {
|
||||
errs[i] = collectorFuncs[collectorName](ch)
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores.
|
||||
func (c *Collector) toLabelName(name string) string {
|
||||
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
|
||||
s = strings.ReplaceAll(s, "__", "_")
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// msToSec converts from ms to seconds.
|
||||
func (c *Collector) msToSec(t float64) float64 {
|
||||
return t / 1000
|
||||
}
|
||||
101
internal/collector/exchange/exchange_active_sync.go
Normal file
101
internal/collector/exchange/exchange_active_sync.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
requestsPerSec = "Requests/sec"
|
||||
pingCommandsPending = "Ping Commands Pending"
|
||||
syncCommandsPerSec = "Sync Commands/sec"
|
||||
)
|
||||
|
||||
// Perflib: [25138] MSExchange ActiveSync.
|
||||
type perflibActiveSync struct {
|
||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||
PingCommandsPending float64 `perflib:"Ping Commands Pending"`
|
||||
SyncCommandsPerSec float64 `perflib:"Sync Commands/sec"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildActiveSync() error {
|
||||
counters := []string{
|
||||
requestsPerSec,
|
||||
pingCommandsPending,
|
||||
syncCommandsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorActiveSync, err = perfdata.NewCollector(perfdata.V1, "MSExchange ActiveSync", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange ActiveSync collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectActiveSync(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibActiveSync
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange ActiveSync"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, instance := range data {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeSyncRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
instance.RequestsPerSec,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pingCommandsPending,
|
||||
prometheus.GaugeValue,
|
||||
instance.PingCommandsPending,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncCommandsPerSec,
|
||||
prometheus.CounterValue,
|
||||
instance.SyncCommandsPerSec,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHActiveSync(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorActiveSync.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange ActiveSync metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange ActiveSync returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeSyncRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pingCommandsPending,
|
||||
prometheus.GaugeValue,
|
||||
data[pingCommandsPending].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncCommandsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[syncCommandsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
164
internal/collector/exchange/exchange_ad_access_processes.go
Normal file
164
internal/collector/exchange/exchange_ad_access_processes.go
Normal file
@@ -0,0 +1,164 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
ldapReadTime = "LDAP Read Time"
|
||||
ldapSearchTime = "LDAP Search Time"
|
||||
ldapWriteTime = "LDAP Write Time"
|
||||
ldapTimeoutErrorsPerSec = "LDAP Timeout Errors/sec"
|
||||
longRunningLDAPOperationsPerMin = "Long Running LDAP Operations/min"
|
||||
)
|
||||
|
||||
// Perflib: [19108] MSExchange ADAccess Processes.
|
||||
type perflibADAccessProcesses struct {
|
||||
Name string
|
||||
|
||||
LDAPReadTime float64 `perflib:"LDAP Read Time"`
|
||||
LDAPSearchTime float64 `perflib:"LDAP Search Time"`
|
||||
LDAPWriteTime float64 `perflib:"LDAP Write Time"`
|
||||
LDAPTimeoutErrorsPerSec float64 `perflib:"LDAP Timeout Errors/sec"`
|
||||
LongRunningLDAPOperationsPerMin float64 `perflib:"Long Running LDAP Operations/min"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildADAccessProcesses() error {
|
||||
counters := []string{
|
||||
ldapReadTime,
|
||||
ldapSearchTime,
|
||||
ldapWriteTime,
|
||||
ldapTimeoutErrorsPerSec,
|
||||
longRunningLDAPOperationsPerMin,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorADAccessProcesses, err = perfdata.NewCollector(perfdata.V1, "MSExchange ADAccess Processes", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange ADAccess Processes collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectADAccessProcesses(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibADAccessProcesses
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange ADAccess Processes"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
labelUseCount := make(map[string]int)
|
||||
|
||||
for _, proc := range data {
|
||||
labelName := c.toLabelName(proc.Name)
|
||||
if strings.HasSuffix(labelName, "_total") {
|
||||
continue
|
||||
}
|
||||
|
||||
// Since we're not including the PID suffix from the instance names in the label names, we get an occasional duplicate.
|
||||
// This seems to affect about 4 instances only of this object.
|
||||
labelUseCount[labelName]++
|
||||
if labelUseCount[labelName] > 1 {
|
||||
labelName = fmt.Sprintf("%s_%d", labelName, labelUseCount[labelName])
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapReadTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(proc.LDAPReadTime),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapSearchTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(proc.LDAPSearchTime),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapWriteTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(proc.LDAPWriteTime),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapTimeoutErrorsPerSec,
|
||||
prometheus.CounterValue,
|
||||
proc.LDAPTimeoutErrorsPerSec,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.longRunningLDAPOperationsPerMin,
|
||||
prometheus.CounterValue,
|
||||
proc.LongRunningLDAPOperationsPerMin*60,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHADAccessProcesses(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorADAccessProcesses.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange ADAccess Processes metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange ADAccess Processes returned empty result set")
|
||||
}
|
||||
|
||||
labelUseCount := make(map[string]int)
|
||||
|
||||
for name, data := range perfData {
|
||||
labelName := c.toLabelName(name)
|
||||
|
||||
// Since we're not including the PID suffix from the instance names in the label names, we get an occasional duplicate.
|
||||
// This seems to affect about 4 instances only of this object.
|
||||
labelUseCount[labelName]++
|
||||
if labelUseCount[labelName] > 1 {
|
||||
labelName = fmt.Sprintf("%s_%d", labelName, labelUseCount[labelName])
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapReadTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(data[ldapReadTime].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapSearchTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(data[ldapSearchTime].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapWriteTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(data[ldapWriteTime].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapTimeoutErrorsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[ldapTimeoutErrorsPerSec].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.longRunningLDAPOperationsPerMin,
|
||||
prometheus.CounterValue,
|
||||
data[longRunningLDAPOperationsPerMin].FirstValue*60,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
71
internal/collector/exchange/exchange_autodiscover.go
Normal file
71
internal/collector/exchange/exchange_autodiscover.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// [29240] MSExchangeAutodiscover.
|
||||
type perflibAutodiscover struct {
|
||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildAutoDiscover() error {
|
||||
counters := []string{
|
||||
requestsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorAutoDiscover, err = perfdata.NewCollector(perfdata.V1, "MSExchange Autodiscover", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectAutoDiscover(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibAutodiscover
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchangeAutodiscover"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, autodisc := range data {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.autoDiscoverRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
autodisc.RequestsPerSec,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHAutoDiscover(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorAutoDiscover.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange Autodiscover metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange Autodiscover returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.autoDiscoverRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
69
internal/collector/exchange/exchange_availability_service.go
Normal file
69
internal/collector/exchange/exchange_availability_service.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Perflib: [24914] MSExchange Availability Service.
|
||||
type perflibAvailabilityService struct {
|
||||
RequestsSec float64 `perflib:"Availability Requests (sec)"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildAvailabilityService() error {
|
||||
counters := []string{}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorAvailabilityService, err = perfdata.NewCollector(perfdata.V1, "MSExchange Availability Service", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange Availability Service collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectAvailabilityService(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibAvailabilityService
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange Availability Service"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, availservice := range data {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.availabilityRequestsSec,
|
||||
prometheus.CounterValue,
|
||||
availservice.RequestsSec,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHAvailabilityService(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorAvailabilityService.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange Availability Service metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange Availability Service returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.availabilityRequestsSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
156
internal/collector/exchange/exchange_http_proxy.go
Normal file
156
internal/collector/exchange/exchange_http_proxy.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
mailboxServerLocatorAverageLatency = "MailboxServerLocator Average Latency (Moving Average)"
|
||||
averageAuthenticationLatency = "Average Authentication Latency"
|
||||
averageCASProcessingLatency = "Average ClientAccess Server Processing Latency"
|
||||
mailboxServerProxyFailureRate = "Mailbox Server Proxy Failure Rate"
|
||||
outstandingProxyRequests = "Outstanding Proxy Requests"
|
||||
proxyRequestsPerSec = "Proxy Requests/Sec"
|
||||
)
|
||||
|
||||
// Perflib: [36934] MSExchange HttpProxy.
|
||||
type perflibHTTPProxy struct {
|
||||
Name string
|
||||
|
||||
MailboxServerLocatorAverageLatency float64 `perflib:"MailboxServerLocator Average Latency (Moving Average)"`
|
||||
AverageAuthenticationLatency float64 `perflib:"Average Authentication Latency"`
|
||||
AverageCASProcessingLatency float64 `perflib:"Average ClientAccess Server Processing Latency"`
|
||||
MailboxServerProxyFailureRate float64 `perflib:"Mailbox Server Proxy Failure Rate"`
|
||||
OutstandingProxyRequests float64 `perflib:"Outstanding Proxy Requests"`
|
||||
ProxyRequestsPerSec float64 `perflib:"Proxy Requests/Sec"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildHTTPProxy() error {
|
||||
counters := []string{
|
||||
mailboxServerLocatorAverageLatency,
|
||||
averageAuthenticationLatency,
|
||||
averageCASProcessingLatency,
|
||||
mailboxServerProxyFailureRate,
|
||||
outstandingProxyRequests,
|
||||
proxyRequestsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorHttpProxy, err = perfdata.NewCollector(perfdata.V1, "MSExchange HttpProxy", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange HttpProxy collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectHTTPProxy(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibHTTPProxy
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange HttpProxy"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, instance := range data {
|
||||
labelName := c.toLabelName(instance.Name)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mailboxServerLocatorAverageLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(instance.MailboxServerLocatorAverageLatency),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.averageAuthenticationLatency,
|
||||
prometheus.GaugeValue,
|
||||
instance.AverageAuthenticationLatency,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.averageCASProcessingLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(instance.AverageCASProcessingLatency),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mailboxServerProxyFailureRate,
|
||||
prometheus.GaugeValue,
|
||||
instance.MailboxServerProxyFailureRate,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outstandingProxyRequests,
|
||||
prometheus.GaugeValue,
|
||||
instance.OutstandingProxyRequests,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.proxyRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
instance.ProxyRequestsPerSec,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHHTTPProxy(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorHttpProxy.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange HttpProxy Service metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange HttpProxy Service returned empty result set")
|
||||
}
|
||||
|
||||
for name, data := range perfData {
|
||||
labelName := c.toLabelName(name)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mailboxServerLocatorAverageLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(data[mailboxServerLocatorAverageLatency].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.averageAuthenticationLatency,
|
||||
prometheus.GaugeValue,
|
||||
data[averageAuthenticationLatency].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.averageCASProcessingLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(data[averageCASProcessingLatency].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mailboxServerProxyFailureRate,
|
||||
prometheus.GaugeValue,
|
||||
data[mailboxServerProxyFailureRate].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outstandingProxyRequests,
|
||||
prometheus.GaugeValue,
|
||||
data[outstandingProxyRequests].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.proxyRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[proxyRequestsPerSec].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
75
internal/collector/exchange/exchange_mapi_http_emsmdb.go
Normal file
75
internal/collector/exchange/exchange_mapi_http_emsmdb.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
activeUserCount = "Active User Count"
|
||||
)
|
||||
|
||||
// perflib [26463] MSExchange MapiHttp Emsmdb.
|
||||
type perflibMapiHttpEmsmdb struct {
|
||||
ActiveUserCount float64 `perflib:"Active User Count"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildMapiHttpEmsmdb() error {
|
||||
counters := []string{
|
||||
activeUserCount,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorMapiHttpEmsmdb, err = perfdata.NewCollector(perfdata.V1, "MSExchange MapiHttp Emsmdb", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange MapiHttp Emsmdb: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectMapiHttpEmsmdb(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibMapiHttpEmsmdb
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange MapiHttp Emsmdb"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, mapihttp := range data {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeUserCountMapiHttpEmsMDB,
|
||||
prometheus.GaugeValue,
|
||||
mapihttp.ActiveUserCount,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHMapiHttpEmsmdb(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorMapiHttpEmsmdb.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange MapiHttp Emsmdb metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange MapiHttp Emsmdb returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeUserCountMapiHttpEmsMDB,
|
||||
prometheus.GaugeValue,
|
||||
data[activeUserCount].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
88
internal/collector/exchange/exchange_outlook_web_access.go
Normal file
88
internal/collector/exchange/exchange_outlook_web_access.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
currentUniqueUsers = "Current Unique Users"
|
||||
// requestsPerSec = "Requests/sec"
|
||||
)
|
||||
|
||||
// Perflib: [24618] MSExchange OWA.
|
||||
type perflibOWA struct {
|
||||
CurrentUniqueUsers float64 `perflib:"Current Unique Users"`
|
||||
RequestsPerSec float64 `perflib:"Requests/sec"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildOWA() error {
|
||||
counters := []string{
|
||||
currentUniqueUsers,
|
||||
requestsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorOWA, err = perfdata.NewCollector(perfdata.V1, "MSExchange OWA", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange OWA collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectOWA(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibOWA
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange OWA"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, owa := range data {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentUniqueUsers,
|
||||
prometheus.GaugeValue,
|
||||
owa.CurrentUniqueUsers,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.owaRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
owa.RequestsPerSec,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHOWA(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorOWA.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange OWA metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange OWA returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentUniqueUsers,
|
||||
prometheus.GaugeValue,
|
||||
data[currentUniqueUsers].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.owaRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
140
internal/collector/exchange/exchange_rpc_client_access.go
Normal file
140
internal/collector/exchange/exchange_rpc_client_access.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
rpcAveragedLatency = "RPC Averaged Latency"
|
||||
rpcRequests = "RPC Requests"
|
||||
// activeUserCount = "Active User Count"
|
||||
connectionCount = "Connection Count"
|
||||
rpcOperationsPerSec = "RPC Operations/sec"
|
||||
userCount = "User Count"
|
||||
)
|
||||
|
||||
// Perflib: [29366] MSExchange RpcClientAccess.
|
||||
type perflibRPCClientAccess struct {
|
||||
RPCAveragedLatency float64 `perflib:"RPC Averaged Latency"`
|
||||
RPCRequests float64 `perflib:"RPC Requests"`
|
||||
ActiveUserCount float64 `perflib:"Active User Count"`
|
||||
ConnectionCount float64 `perflib:"Connection Count"`
|
||||
RPCOperationsPerSec float64 `perflib:"RPC Operations/sec"`
|
||||
UserCount float64 `perflib:"User Count"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildRPC() error {
|
||||
counters := []string{
|
||||
rpcAveragedLatency,
|
||||
rpcRequests,
|
||||
activeUserCount,
|
||||
connectionCount,
|
||||
rpcOperationsPerSec,
|
||||
userCount,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorRpcClientAccess, err = perfdata.NewCollector(perfdata.V1, "MSExchange RpcClientAccess", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange RpcClientAccess collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectRPC(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibRPCClientAccess
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchange RpcClientAccess"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, rpc := range data {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcAveragedLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(rpc.RPCAveragedLatency),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcRequests,
|
||||
prometheus.GaugeValue,
|
||||
rpc.RPCRequests,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeUserCount,
|
||||
prometheus.GaugeValue,
|
||||
rpc.ActiveUserCount,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionCount,
|
||||
prometheus.GaugeValue,
|
||||
rpc.ConnectionCount,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcOperationsPerSec,
|
||||
prometheus.CounterValue,
|
||||
rpc.RPCOperationsPerSec,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.userCount,
|
||||
prometheus.GaugeValue,
|
||||
rpc.UserCount,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHRPC(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorRpcClientAccess.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange RpcClientAccess: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange RpcClientAccess returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcAveragedLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(data[rpcAveragedLatency].FirstValue),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcRequests,
|
||||
prometheus.GaugeValue,
|
||||
data[rpcRequests].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeUserCount,
|
||||
prometheus.GaugeValue,
|
||||
data[activeUserCount].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionCount,
|
||||
prometheus.GaugeValue,
|
||||
data[connectionCount].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcOperationsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[rpcOperationsPerSec].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.userCount,
|
||||
prometheus.GaugeValue,
|
||||
data[userCount].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package exchange_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/exchange"
|
||||
"github.com/prometheus-community/windows_exporter/internal/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
191
internal/collector/exchange/exchange_transport_queues.go
Normal file
191
internal/collector/exchange/exchange_transport_queues.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
v1 "github.com/prometheus-community/windows_exporter/internal/perfdata/v1"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
externalActiveRemoteDeliveryQueueLength = "External Active Remote Delivery Queue Length"
|
||||
internalActiveRemoteDeliveryQueueLength = "Internal Active Remote Delivery Queue Length"
|
||||
activeMailboxDeliveryQueueLength = "Active Mailbox Delivery Queue Length"
|
||||
retryMailboxDeliveryQueueLength = "Retry Mailbox Delivery Queue Length"
|
||||
unreachableQueueLength = "Unreachable Queue Length"
|
||||
externalLargestDeliveryQueueLength = "External Largest Delivery Queue Length"
|
||||
internalLargestDeliveryQueueLength = "Internal Largest Delivery Queue Length"
|
||||
poisonQueueLength = "Poison Queue Length"
|
||||
)
|
||||
|
||||
// Perflib: [20524] MSExchangeTransport Queues.
|
||||
type perflibTransportQueues struct {
|
||||
Name string
|
||||
|
||||
ExternalActiveRemoteDeliveryQueueLength float64 `perflib:"External Active Remote Delivery Queue Length"`
|
||||
InternalActiveRemoteDeliveryQueueLength float64 `perflib:"Internal Active Remote Delivery Queue Length"`
|
||||
ActiveMailboxDeliveryQueueLength float64 `perflib:"Active Mailbox Delivery Queue Length"`
|
||||
RetryMailboxDeliveryQueueLength float64 `perflib:"Retry Mailbox Delivery Queue Length"`
|
||||
UnreachableQueueLength float64 `perflib:"Unreachable Queue Length"`
|
||||
ExternalLargestDeliveryQueueLength float64 `perflib:"External Largest Delivery Queue Length"`
|
||||
InternalLargestDeliveryQueueLength float64 `perflib:"Internal Largest Delivery Queue Length"`
|
||||
PoisonQueueLength float64 `perflib:"Poison Queue Length"`
|
||||
}
|
||||
|
||||
func (c *Collector) buildTransportQueues() error {
|
||||
counters := []string{
|
||||
externalActiveRemoteDeliveryQueueLength,
|
||||
internalActiveRemoteDeliveryQueueLength,
|
||||
activeMailboxDeliveryQueueLength,
|
||||
retryMailboxDeliveryQueueLength,
|
||||
unreachableQueueLength,
|
||||
externalLargestDeliveryQueueLength,
|
||||
internalLargestDeliveryQueueLength,
|
||||
poisonQueueLength,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorTransportQueues, err = perfdata.NewCollector(perfdata.V1, "MSExchangeTransport Queues", perfdata.AllInstances, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchangeTransport Queues collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectTransportQueues(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
var data []perflibTransportQueues
|
||||
|
||||
if err := v1.UnmarshalObject(ctx.PerfObjects["MSExchangeTransport Queues"], &data, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, queue := range data {
|
||||
labelName := c.toLabelName(queue.Name)
|
||||
if strings.HasSuffix(labelName, "_total") {
|
||||
continue
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalActiveRemoteDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.ExternalActiveRemoteDeliveryQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.internalActiveRemoteDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.InternalActiveRemoteDeliveryQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeMailboxDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.ActiveMailboxDeliveryQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retryMailboxDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.RetryMailboxDeliveryQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.unreachableQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.UnreachableQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalLargestDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.ExternalLargestDeliveryQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.internalLargestDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.InternalLargestDeliveryQueueLength,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.poisonQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
queue.PoisonQueueLength,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHTransportQueues(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorTransportQueues.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchangeTransport Queues: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchangeTransport Queues returned empty result set")
|
||||
}
|
||||
|
||||
for name, data := range perfData {
|
||||
labelName := c.toLabelName(name)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalActiveRemoteDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[externalActiveRemoteDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.internalActiveRemoteDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[internalActiveRemoteDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeMailboxDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[activeMailboxDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retryMailboxDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[retryMailboxDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.unreachableQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[unreachableQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalLargestDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[externalLargestDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.internalLargestDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[internalLargestDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.poisonQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[poisonQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user