mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-11 15:36:37 +00:00
Compare commits
148 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dffc53eff8 | ||
|
|
9026bc02ff | ||
|
|
8f2a45d832 | ||
|
|
6cecc735df | ||
|
|
4635be8c0c | ||
|
|
4cc7d108e3 | ||
|
|
d878423cb6 | ||
|
|
a93bbe4ac2 | ||
|
|
33efbdfbcb | ||
|
|
8db705e67a | ||
|
|
7044b556c2 | ||
|
|
fa8d28c181 | ||
|
|
64c8423e61 | ||
|
|
e2e1141973 | ||
|
|
31bb6d03ee | ||
|
|
caee5a05fe | ||
|
|
578b16b448 | ||
|
|
1da96a4f3c | ||
|
|
fddb92a9d5 | ||
|
|
2cda7b3f4d | ||
|
|
b44b0413bb | ||
|
|
f4e360218f | ||
|
|
4efb502aab | ||
|
|
a4a5ac464a | ||
|
|
1b438cdb82 | ||
|
|
f0d0545d34 | ||
|
|
d05effdda5 | ||
|
|
2d29f0004b | ||
|
|
d94640b6f8 | ||
|
|
26e05e9d07 | ||
|
|
9eec34d2f1 | ||
|
|
b8b164bfca | ||
|
|
7775ef95e6 | ||
|
|
eeaefba0d7 | ||
|
|
b2ab542b6d | ||
|
|
f85866ce1e | ||
|
|
9e24ce8f74 | ||
|
|
9c65b7464f | ||
|
|
c242fae84c | ||
|
|
c85cfaadde | ||
|
|
d6c24d1500 | ||
|
|
8b515ba54a | ||
|
|
a2575b93a9 | ||
|
|
965be334bc | ||
|
|
1239fbf719 | ||
|
|
a49dee606b | ||
|
|
c713bed4e3 | ||
|
|
99b6d215a2 | ||
|
|
6d91cdc9fc | ||
|
|
c9ebc3e153 | ||
|
|
c99cf180d0 | ||
|
|
6e14d4e53f | ||
|
|
48e7c34539 | ||
|
|
6497a1a5cc | ||
|
|
4e1987686b | ||
|
|
dc4bc8e163 | ||
|
|
b8747045ce | ||
|
|
00781dbbee | ||
|
|
195cfa8d5c | ||
|
|
be25d79b71 | ||
|
|
9bf84fb10c | ||
|
|
b977c8484b | ||
|
|
13ebec0195 | ||
|
|
cc89ae33a4 | ||
|
|
215032a111 | ||
|
|
a2fe96fbc8 | ||
|
|
7d8cf59dac | ||
|
|
de8a1ebbfe | ||
|
|
5ff820cfd0 | ||
|
|
8f6a1e3f07 | ||
|
|
f6b91e5cb0 | ||
|
|
f21c119c74 | ||
|
|
e7464d9fcf | ||
|
|
87d1a59a57 | ||
|
|
b1c272a996 | ||
|
|
fdf6f33941 | ||
|
|
72e7096110 | ||
|
|
658fbd92ab | ||
|
|
d503ae05d4 | ||
|
|
c8b06e86b0 | ||
|
|
21a64b1a62 | ||
|
|
6a15aff837 | ||
|
|
802f0df07a | ||
|
|
08c67def1e | ||
|
|
65c9009db6 | ||
|
|
8e2e867b11 | ||
|
|
7a201e0c16 | ||
|
|
0ebb2d36e8 | ||
|
|
3a2c61c19d | ||
|
|
8a1972162a | ||
|
|
032b1f5e88 | ||
|
|
1daaccceaf | ||
|
|
154dec5f4c | ||
|
|
dbb890c00f | ||
|
|
1515623618 | ||
|
|
96c1412a5b | ||
|
|
e0bdc9828c | ||
|
|
6e9daff6ed | ||
|
|
91da7562e1 | ||
|
|
c238bbcaf2 | ||
|
|
c382d0c217 | ||
|
|
9d1c9fb012 | ||
|
|
f3ef7583fe | ||
|
|
f37d4d7921 | ||
|
|
39ab9faa6a | ||
|
|
ac7c98e57e | ||
|
|
377fec7b55 | ||
|
|
548b970288 | ||
|
|
a02d0257b3 | ||
|
|
477ec0df50 | ||
|
|
2a88229a0e | ||
|
|
3cbf5dc085 | ||
|
|
c4a4da07f8 | ||
|
|
e2ea99fadd | ||
|
|
6eebfcce57 | ||
|
|
f97ac3fb66 | ||
|
|
7f7239f404 | ||
|
|
8d1d552351 | ||
|
|
233470cdf0 | ||
|
|
67fca296bf | ||
|
|
143ab2247a | ||
|
|
7635e6e094 | ||
|
|
9541560e43 | ||
|
|
941019ebc9 | ||
|
|
5ef7c1f0e9 | ||
|
|
9b5568354c | ||
|
|
eab87292c1 | ||
|
|
6ca67f7aa2 | ||
|
|
688ea45e7e | ||
|
|
4032b7f610 | ||
|
|
e2ceb0d46d | ||
|
|
d07845ca08 | ||
|
|
b5284aca85 | ||
|
|
5c1f19d4bc | ||
|
|
c83da9a2f0 | ||
|
|
b09b8a9c36 | ||
|
|
265c12b28e | ||
|
|
2be970e652 | ||
|
|
2103e7e1b5 | ||
|
|
09c0e47fde | ||
|
|
e19b8959c4 | ||
|
|
21a7beaee6 | ||
|
|
a32f83a6de | ||
|
|
f70fa009de | ||
|
|
546e5de5e1 | ||
|
|
415c72d457 | ||
|
|
bd7d7be6ea | ||
|
|
b4c0874ca4 |
6
.editorconfig
Normal file
6
.editorconfig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*.wxs]
|
||||||
|
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
71
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
71
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
name: 🐞 Bug
|
||||||
|
description: Something is not working as indended.
|
||||||
|
labels: [ 🐞 bug ]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: Thanks for taking the time to fill out this bug report!
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Current Behavior
|
||||||
|
description: A concise description of what you're experiencing.
|
||||||
|
placeholder: |
|
||||||
|
When I do <X>, <Y> happens and I see the error message attached below:
|
||||||
|
```...```
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
description: A concise description of what you expected to happen.
|
||||||
|
placeholder: When I do <X>, <Z> should happen instead.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps To Reproduce
|
||||||
|
description: Steps to reproduce the behavior.
|
||||||
|
placeholder: |
|
||||||
|
1. In this environment...
|
||||||
|
2. With this config...
|
||||||
|
3. Run '...'
|
||||||
|
4. See error...
|
||||||
|
render: Markdown
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Environment
|
||||||
|
description: |
|
||||||
|
examples:
|
||||||
|
- **windows_exporter Version**: 0.26
|
||||||
|
- **Windows Server Version**: 2019
|
||||||
|
value: |
|
||||||
|
- windows_exporter Version:
|
||||||
|
- Windows Server Version:
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: windows_exporter logs
|
||||||
|
description: |
|
||||||
|
Log of windows_exporter.
|
||||||
|
⚠️ Without proving logs, we unable to assist here. ⚠️
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Anything else?
|
||||||
|
description: |
|
||||||
|
Links? References? Anything that will give us more context about the issue you are encountering!
|
||||||
|
|
||||||
|
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
41
.github/ISSUE_TEMPLATE/enhancement.yaml
vendored
Normal file
41
.github/ISSUE_TEMPLATE/enhancement.yaml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
name: ✨ Enhancement / Feature / Task
|
||||||
|
description: Some feature is missing or incomplete.
|
||||||
|
labels: [ ✨ enhancement ]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Problem Statement
|
||||||
|
description: Without specifying a solution, describe what the project is missing today.
|
||||||
|
placeholder: |
|
||||||
|
The rotating project logo has a fixed size and color.
|
||||||
|
There is no way to make it larger and more shiny.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Proposed Solution
|
||||||
|
description: Describe the proposed solution to the problem above.
|
||||||
|
placeholder: |
|
||||||
|
- Implement 2 new flags CLI: ```--logo-color=FFD700``` and ```--logo-size=100```
|
||||||
|
- Let these flags control the size of the rotating project logo.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional information
|
||||||
|
placeholder: |
|
||||||
|
We considered adjusting the logo size to the phase of the moon, but there was no
|
||||||
|
reliable data source in air-gapped environments.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Acceptance Criteria
|
||||||
|
placeholder: |
|
||||||
|
- [ ] As a user, I can control the size of the rotating logo using a CLI flag.
|
||||||
|
- [ ] As a user, I can control the color of the rotating logo using a CLI flag.
|
||||||
|
- [ ] Defaults are reasonably set.
|
||||||
|
- [ ] New settings are appropriately documented.
|
||||||
|
- [ ] No breaking change for current users of the rotating logo feature.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
27
.github/ISSUE_TEMPLATE/question.yaml
vendored
Normal file
27
.github/ISSUE_TEMPLATE/question.yaml
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
name: ❓ Question
|
||||||
|
description: Something is not clear.
|
||||||
|
labels: [ ❓ question ]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Problem Statement
|
||||||
|
description: Without specifying a solution, describe what the project is missing today.
|
||||||
|
placeholder: |
|
||||||
|
The rotating project logo has a fixed size and color.
|
||||||
|
There is no way to make it larger and more shiny.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Environment
|
||||||
|
description: |
|
||||||
|
examples:
|
||||||
|
- **windows_exporter Version**: 0.26
|
||||||
|
- **Windows Server Version**: 2019
|
||||||
|
value: |
|
||||||
|
- windows_exporter Version:
|
||||||
|
- Windows Server Version:
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
9
.github/dependabot.yml
vendored
9
.github/dependabot.yml
vendored
@@ -1,6 +1,15 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
labels:
|
||||||
|
- "🛠️ dependencies"
|
||||||
|
|
||||||
- package-ecosystem: "gomod"
|
- package-ecosystem: "gomod"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
|
labels:
|
||||||
|
- "🛠️ dependencies"
|
||||||
|
|||||||
23
.github/release.yml
vendored
Normal file
23
.github/release.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
changelog:
|
||||||
|
exclude:
|
||||||
|
labels:
|
||||||
|
- chore
|
||||||
|
categories:
|
||||||
|
- title: 💥 Breaking Changes
|
||||||
|
labels:
|
||||||
|
- 💥 breaking-change
|
||||||
|
- title: ✨ Exciting New Features
|
||||||
|
labels:
|
||||||
|
- ✨ enhancement
|
||||||
|
- title: 🐞 Bug Fixes
|
||||||
|
labels:
|
||||||
|
- 🐞 bug
|
||||||
|
- title: 🛠️ Dependencies
|
||||||
|
labels:
|
||||||
|
- 🛠️ dependencies
|
||||||
|
- title: 📖 Documentation
|
||||||
|
labels:
|
||||||
|
- 📖 docs
|
||||||
|
- title: Other Changes
|
||||||
|
labels:
|
||||||
|
- "*"
|
||||||
57
.github/workflows/container_description.yml
vendored
Normal file
57
.github/workflows/container_description.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
name: Push README to Docker Hub
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- "README.md"
|
||||||
|
- "README-containers.md"
|
||||||
|
- ".github/workflows/container_description.yml"
|
||||||
|
branches: [ main, master ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
PushDockerHubReadme:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Push README to Docker Hub
|
||||||
|
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 docker hub repo name
|
||||||
|
run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
|
||||||
|
- name: Push README to Dockerhub
|
||||||
|
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
|
||||||
|
env:
|
||||||
|
DOCKER_USER: ${{ secrets.DOCKER_HUB_LOGIN }}
|
||||||
|
DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
|
with:
|
||||||
|
destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
|
||||||
|
provider: dockerhub
|
||||||
|
short_description: ${{ env.DOCKER_REPO_NAME }}
|
||||||
|
# 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: ''
|
||||||
28
.github/workflows/lint.yml
vendored
28
.github/workflows/lint.yml
vendored
@@ -30,8 +30,8 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
|
|
||||||
@@ -44,7 +44,6 @@ jobs:
|
|||||||
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
|
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"
|
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||||
|
|
||||||
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.2.0
|
|
||||||
# GOPATH\bin dir must be appended to PATH else the `promu` command won't be found
|
# 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
|
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||||
|
|
||||||
@@ -54,8 +53,8 @@ jobs:
|
|||||||
promtool:
|
promtool:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
|
|
||||||
@@ -69,8 +68,6 @@ jobs:
|
|||||||
Expand-Archive -Path promu-$($Env:PROMU_VER).windows-amd64.zip -DestinationPath .
|
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"
|
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||||
|
|
||||||
# No binaries available so build from source
|
|
||||||
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.2.0
|
|
||||||
# GOPATH\bin dir must be appended to PATH else the `promu` command won't be found
|
# 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
|
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||||
|
|
||||||
@@ -95,20 +92,13 @@ jobs:
|
|||||||
git config --global core.autocrlf false
|
git config --global core.autocrlf false
|
||||||
git config --global core.eol lf
|
git config --global core.eol lf
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
|
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v6
|
||||||
with:
|
with:
|
||||||
version: v1.55.2
|
version: v1.58
|
||||||
args: "--timeout=5m"
|
args: "--timeout=5m --out-format github-actions,colored-line-number"
|
||||||
|
|
||||||
# golangci-lint action doesn't always provide helpful output, so re-run without the action for
|
|
||||||
# better output of the problem.
|
|
||||||
# The cache from the golangci-lint step is re-used here, so this step should finish quickly.
|
|
||||||
- name: errors
|
|
||||||
if: ${{ failure() }}
|
|
||||||
run: golangci-lint run --timeout=5m -c .golangci.yaml
|
|
||||||
46
.github/workflows/pr-check.yaml
vendored
Normal file
46
.github/workflows/pr-check.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: Validate Pull Request
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- reopened
|
||||||
|
- synchronize
|
||||||
|
- labeled
|
||||||
|
- unlabeled
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
required-labels-missing:
|
||||||
|
name: required labels missing
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: check
|
||||||
|
if: >-
|
||||||
|
!contains(github.event.pull_request.labels.*.name, '💥 breaking-change')
|
||||||
|
&& !contains(github.event.pull_request.labels.*.name, '✨ enhancement')
|
||||||
|
&& !contains(github.event.pull_request.labels.*.name, '🐞 bug')
|
||||||
|
&& !contains(github.event.pull_request.labels.*.name, '📖 docs')
|
||||||
|
&& !contains(github.event.pull_request.labels.*.name, 'chore')
|
||||||
|
&& !contains(github.event.pull_request.labels.*.name, '🛠️ dependencies')
|
||||||
|
run: >-
|
||||||
|
echo One of the following labels is missing on this PR:
|
||||||
|
breaking-change
|
||||||
|
enhancement
|
||||||
|
bug
|
||||||
|
docs
|
||||||
|
chore
|
||||||
|
&& exit 1
|
||||||
|
title:
|
||||||
|
name: check title prefix
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: check
|
||||||
|
run: |
|
||||||
|
PR_TITLE_PREFIX=$(echo "$PR_TITLE" | cut -d':' -f1)
|
||||||
|
if [[ ! -d "pkg/collector/$PR_TITLE_PREFIX" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]]; then
|
||||||
|
echo "PR title must start with an name of an collector package"
|
||||||
|
echo "Example: 'logical_disk: description'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
103
.github/workflows/release.yml
vendored
103
.github/workflows/release.yml
vendored
@@ -2,6 +2,10 @@ name: Releases
|
|||||||
|
|
||||||
# Trigger on releases.
|
# Trigger on releases.
|
||||||
on:
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
- published
|
- published
|
||||||
@@ -18,15 +22,40 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# fetch-depth required for gitversion in `Build` step
|
# fetch-depth required for gitversion in `Build` step
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
|
|
||||||
|
# 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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
- uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
driver: remote
|
||||||
|
endpoint: npipe:////./pipe/buildkitd
|
||||||
|
|
||||||
- name: Install WiX
|
- name: Install WiX
|
||||||
run: dotnet tool install --global wix
|
run: dotnet tool install --global wix
|
||||||
|
|
||||||
@@ -37,60 +66,82 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Build deps
|
- name: Install Build deps
|
||||||
run: |
|
run: |
|
||||||
dotnet tool install --global GitVersion.Tool --version 5.*
|
|
||||||
Invoke-WebRequest -Uri https://github.com/prometheus/promu/releases/download/v$($Env:PROMU_VER)/promu-$($Env:PROMU_VER).windows-amd64.zip -OutFile promu-$($Env:PROMU_VER).windows-amd64.zip
|
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 .
|
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"
|
Copy-Item -Path promu-$($Env:PROMU_VER).windows-amd64\promu.exe -Destination "$(go env GOPATH)\bin"
|
||||||
|
|
||||||
# No binaries available so build from source
|
# GOPATH\bin dir must be added to PATH else the `promu` commands won't be found
|
||||||
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.0
|
|
||||||
# GOPATH\bin dir must be added to PATH else the `promu` and `goversioninfo` commands won't be found
|
|
||||||
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
echo "$(go env GOPATH)\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
dotnet-gitversion /output json /showvariable FullSemVer | Set-Content VERSION -PassThru
|
$Version = git describe --tag
|
||||||
$Version = Get-Content VERSION
|
$Version = $Version -replace 'v', ''
|
||||||
# Windows versioninfo resources need the file version by parts (but product version is free text)
|
|
||||||
$VersionParts = ($Version -replace '^v?([0-9\.]+).*$','$1').Split(".")
|
|
||||||
goversioninfo.exe -ver-major $VersionParts[0] -ver-minor $VersionParts[1] -ver-patch $VersionParts[2] -product-version $Version -platform-specific
|
|
||||||
|
|
||||||
make crossbuild
|
|
||||||
# '+' symbols are invalid characters in image tags
|
# '+' symbols are invalid characters in image tags
|
||||||
(Get-Content -Path VERSION) -replace '\+', '_' | Set-Content -Path VERSION
|
$Version = $Version -replace '\+', '_'
|
||||||
|
$Version | Set-Content VERSION -PassThru
|
||||||
|
|
||||||
make build-all
|
make build-all
|
||||||
|
|
||||||
# GH requires all files to have different names, so add version/arch to differentiate
|
# GH requires all files to have different names, so add version/arch to differentiate
|
||||||
foreach($Arch in "amd64", "arm64") {
|
foreach($Arch in "amd64", "arm64") {
|
||||||
Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe
|
Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Get-ChildItem -Path output
|
||||||
|
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: windows_exporter_binaries
|
name: windows_exporter_binaries
|
||||||
path: output\windows_exporter-*.exe
|
path: output\windows_exporter-*.exe
|
||||||
|
|
||||||
- name: Build Release Artifacts
|
- name: Build Release Artifacts
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
run: |
|
run: |
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
$BuildVersion = Get-Content VERSION
|
$Version = Get-Content VERSION
|
||||||
$TagName = $env:GITHUB_REF -replace 'refs/tags/', ''
|
|
||||||
# The MSI version is not semver compliant, so just take the numerical parts
|
|
||||||
$MSIVersion = $TagName -replace '^v?([0-9\.]+).*$','$1'
|
|
||||||
foreach($Arch in "amd64", "arm64") {
|
foreach($Arch in "amd64", "arm64") {
|
||||||
Write-Verbose "Building windows_exporter $MSIVersion msi for $Arch"
|
Write-Host "Building windows_exporter $Version msi for $Arch"
|
||||||
.\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$BuildVersion-$Arch.exe -Version $MSIVersion -Arch "$Arch"
|
.\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch"
|
||||||
Move-Item installer\windows_exporter-$MSIVersion-$Arch.msi output\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Move-Item installer\*.msi output\
|
||||||
|
Get-ChildItem -Path output\
|
||||||
|
|
||||||
promu checksum output\
|
promu checksum output\
|
||||||
|
|
||||||
|
- name: Build Docker Artifacts
|
||||||
|
run: make build-all
|
||||||
|
env:
|
||||||
|
VERSION: >-
|
||||||
|
${{
|
||||||
|
startsWith(github.ref, 'refs/tags/') && 'latest' ||
|
||||||
|
(
|
||||||
|
github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || github.ref_name
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_HUB_LOGIN }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
|
|
||||||
|
#- name: Login to quay.io
|
||||||
|
# if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
# uses: docker/login-action@v3
|
||||||
|
# with:
|
||||||
|
# registry: quay.io
|
||||||
|
# username: 'robot'
|
||||||
|
# password: ${{ secrets.QUAY_IO_API_TOKEN }}
|
||||||
|
|
||||||
- name: Login to GitHub container registry
|
- name: Login to GitHub container registry
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
@@ -100,8 +151,8 @@ jobs:
|
|||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
VERSION: ${{ startsWith(github.ref, 'refs/tags/') && 'latest' || github.ref_name }}
|
||||||
run: |
|
run: |
|
||||||
$Env:VERSION = 'latest'
|
|
||||||
make push-all
|
make push-all
|
||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
|
|||||||
2
.github/workflows/spelling.yml
vendored
2
.github/workflows/spelling.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
name: Check for spelling errors
|
name: Check for spelling errors
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: codespell-project/actions-codespell@master
|
- uses: codespell-project/actions-codespell@master
|
||||||
with:
|
with:
|
||||||
check_filenames: true
|
check_filenames: true
|
||||||
|
|||||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v8
|
- uses: actions/stale@v9
|
||||||
with:
|
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.'
|
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'
|
exempt-issue-labels: 'lifecycle/frozen'
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,3 +6,6 @@ output/
|
|||||||
.vscode
|
.vscode
|
||||||
.idea
|
.idea
|
||||||
*.syso
|
*.syso
|
||||||
|
installer/*.msi
|
||||||
|
installer/*.wixpdb
|
||||||
|
local/
|
||||||
106
.golangci.yaml
106
.golangci.yaml
@@ -1,14 +1,100 @@
|
|||||||
linters:
|
linters:
|
||||||
disable-all: true
|
enable-all: true
|
||||||
enable:
|
disable:
|
||||||
- deadcode
|
- asasalint
|
||||||
- errcheck
|
- asciicheck
|
||||||
- revive
|
- bidichk
|
||||||
- govet
|
- bodyclose
|
||||||
- gofmt
|
- canonicalheader
|
||||||
- ineffassign
|
- containedctx
|
||||||
- unconvert
|
- contextcheck
|
||||||
- varcheck
|
- copyloopvar
|
||||||
|
- cyclop
|
||||||
|
- decorder
|
||||||
|
- depguard
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- dupword
|
||||||
|
- durationcheck
|
||||||
|
- err113
|
||||||
|
- errchkjson
|
||||||
|
- errname
|
||||||
|
- errorlint
|
||||||
|
- exhaustive
|
||||||
|
- exhaustruct
|
||||||
|
- exportloopref
|
||||||
|
- fatcontext
|
||||||
|
- forbidigo
|
||||||
|
- forcetypeassert
|
||||||
|
- funlen
|
||||||
|
- gci
|
||||||
|
- ginkgolinter
|
||||||
|
- gocheckcompilerdirectives
|
||||||
|
- gochecknoglobals
|
||||||
|
- gochecknoinits
|
||||||
|
- gochecksumtype
|
||||||
|
- gocognit
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- godot
|
||||||
|
- godox
|
||||||
|
- gofumpt
|
||||||
|
- goheader
|
||||||
|
- goimports
|
||||||
|
- gomoddirectives
|
||||||
|
- gomodguard
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- gosimple
|
||||||
|
- gosmopolitan
|
||||||
|
- grouper
|
||||||
|
- importas
|
||||||
|
- inamedparam
|
||||||
|
- interfacebloat
|
||||||
|
- intrange
|
||||||
|
- ireturn
|
||||||
|
- lll
|
||||||
|
- maintidx
|
||||||
|
- makezero
|
||||||
|
- mirror
|
||||||
|
- misspell
|
||||||
|
- mnd
|
||||||
|
- musttag
|
||||||
|
- nakedret
|
||||||
|
- nestif
|
||||||
|
- nlreturn
|
||||||
|
- noctx
|
||||||
|
- nolintlint
|
||||||
|
- nonamedreturns
|
||||||
|
- nosprintfhostport
|
||||||
|
- paralleltest
|
||||||
|
- predeclared
|
||||||
|
- protogetter
|
||||||
|
- reassign
|
||||||
|
- rowserrcheck
|
||||||
|
- sloglint
|
||||||
|
- spancheck
|
||||||
|
- sqlclosecheck
|
||||||
|
- staticcheck
|
||||||
|
- stylecheck
|
||||||
|
- tagalign
|
||||||
|
- tagliatelle
|
||||||
|
- tenv
|
||||||
|
- testableexamples
|
||||||
|
- testifylint
|
||||||
|
- testpackage
|
||||||
|
- thelper
|
||||||
|
- tparallel
|
||||||
|
- usestdlibvars
|
||||||
|
- varnamelen
|
||||||
|
- wastedassign
|
||||||
|
- whitespace
|
||||||
|
- wrapcheck
|
||||||
|
- wsl
|
||||||
|
- zerologlint
|
||||||
|
- execinquery
|
||||||
|
- gomnd
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude:
|
exclude:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Note this image doesn't really matter for hostprocess but it is good to build per OS version
|
# Note this image doesn't really matter for hostprocess but it is good to build per OS version
|
||||||
# the files in the image are copied to $env:CONTAINER_SANDBOX_MOUNT_POINT on the host
|
# the files in the image are copied to $env:CONTAINER_SANDBOX_MOUNT_POINT on the host
|
||||||
# but the file system is the Host NOT the container
|
# but the file system is the Host NOT the container
|
||||||
ARG BASE="mcr.microsoft.com/windows/nanoserver:1809"
|
ARG BASE="mcr.microsoft.com/windows/nanoserver:ltsc2022"
|
||||||
FROM $BASE
|
FROM $BASE
|
||||||
|
|
||||||
ENV PATH="C:\Windows\system32;C:\Windows;"
|
ENV PATH="C:\Windows\system32;C:\Windows;"
|
||||||
|
|||||||
75
Makefile
75
Makefile
@@ -1,26 +1,35 @@
|
|||||||
export GOOS=windows
|
GOOS ?= windows
|
||||||
export DOCKER_IMAGE_NAME ?= windows-exporter
|
VERSION ?= $(shell cat VERSION)
|
||||||
export DOCKER_REPO ?= ghcr.io/prometheus-community
|
DOCKER ?= docker
|
||||||
|
|
||||||
VERSION?=$(shell cat VERSION)
|
# DOCKER_REPO is the official image repository name at docker.io, quay.io.
|
||||||
DOCKER?=docker
|
DOCKER_REPO ?= prometheuscommunity
|
||||||
|
DOCKER_IMAGE_NAME ?= windows-exporter
|
||||||
|
|
||||||
# Image Variables for Hostprocess Container
|
# 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)
|
||||||
|
|
||||||
|
# Image Variables for host process Container
|
||||||
# Windows image build is heavily influenced by https://github.com/kubernetes/kubernetes/blob/master/cluster/images/etcd/Makefile
|
# Windows image build is heavily influenced by https://github.com/kubernetes/kubernetes/blob/master/cluster/images/etcd/Makefile
|
||||||
OS=1809
|
OS ?= ltsc2019
|
||||||
ALL_OS:= 1809 ltsc2022
|
ALL_OS ?= ltsc2019 ltsc2022
|
||||||
BASE_IMAGE=mcr.microsoft.com/windows/nanoserver
|
BASE_IMAGE ?= mcr.microsoft.com/windows/nanoserver
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: windows_exporter.exe
|
build: generate windows_exporter.exe
|
||||||
|
|
||||||
windows_exporter.exe: pkg/**/*.go
|
windows_exporter.exe: pkg/**/*.go
|
||||||
promu build -v
|
promu build -v
|
||||||
|
|
||||||
|
.PHONY: generate
|
||||||
|
generate:
|
||||||
|
go generate ./...
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -v ./...
|
go test -v ./...
|
||||||
|
|
||||||
bench:
|
bench:
|
||||||
go test -v -bench='benchmarkcollector' ./pkg/collector/{cpu,logical_disk,physical_disk,logon,memory,net,process,service,system,tcp,time}
|
go test -v -bench='benchmarkcollector' ./pkg/collector/{cpu,logical_disk,physical_disk,logon,memory,net,printer,process,service,system,tcp,time}
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
golangci-lint -c .golangci.yaml run
|
golangci-lint -c .golangci.yaml run
|
||||||
@@ -36,28 +45,52 @@ promtool: windows_exporter.exe
|
|||||||
fmt:
|
fmt:
|
||||||
gofmt -l -w -s .
|
gofmt -l -w -s .
|
||||||
|
|
||||||
crossbuild:
|
crossbuild: generate
|
||||||
# The prometheus/golang-builder image for promu crossbuild doesn't exist
|
# The prometheus/golang-builder image for promu crossbuild doesn't exist
|
||||||
# on Windows, so for now, we'll just build twice
|
# on Windows, so for now, we'll just build twice
|
||||||
GOARCH=amd64 promu build --prefix=output/amd64
|
GOARCH=amd64 promu build --prefix=output/amd64
|
||||||
GOARCH=arm64 promu build --prefix=output/arm64
|
GOARCH=arm64 promu build --prefix=output/arm64
|
||||||
|
|
||||||
|
.PHONY: package
|
||||||
|
package: crossbuild
|
||||||
|
powershell -NonInteractive -ExecutionPolicy Bypass -File .\installer\build.ps1 -PathToExecutable .\output\amd64\windows_exporter.exe -Version $(shell git describe --tags --abbrev=0)
|
||||||
|
|
||||||
build-image: crossbuild
|
build-image: crossbuild
|
||||||
$(DOCKER) build --build-arg=BASE=$(BASE_IMAGE):$(OS) -f Dockerfile -t $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$(OS) .
|
$(DOCKER) build --build-arg=BASE=$(BASE_IMAGE):$(OS) -f Dockerfile -t local/$(DOCKER_IMAGE_NAME):$(VERSION)-$(OS) .
|
||||||
|
|
||||||
|
build-hostprocess:
|
||||||
|
$(DOCKER) buildx build --build-arg=BASE=mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0 -f Dockerfile -t local/$(DOCKER_IMAGE_NAME):$(VERSION)-hostprocess .
|
||||||
|
|
||||||
sub-build-%:
|
sub-build-%:
|
||||||
$(MAKE) OS=$* build-image
|
$(MAKE) OS=$* build-image
|
||||||
|
|
||||||
build-all: $(addprefix sub-build-,$(ALL_OS))
|
build-all: $(addprefix sub-build-,$(ALL_OS)) build-hostprocess
|
||||||
|
|
||||||
push:
|
push:
|
||||||
set -x; \
|
set -x; \
|
||||||
for osversion in ${ALL_OS}; do \
|
for docker_repo in ${DOCKER_REPO}; do \
|
||||||
$(DOCKER) push $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
for osversion in ${ALL_OS}; do \
|
||||||
$(DOCKER) manifest create --amend $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION) $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
$(DOCKER) tag local/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion} $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||||
full_version=`$(DOCKER) manifest inspect $(BASE_IMAGE):$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \
|
$(DOCKER) push $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||||
$(DOCKER) manifest annotate --os windows --arch amd64 --os-version $${full_version} $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION) $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
$(DOCKER) manifest create --amend $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||||
|
full_version=`$(DOCKER) manifest inspect $(BASE_IMAGE):$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \
|
||||||
|
$(DOCKER) manifest annotate --os windows --arch amd64 --os-version $${full_version} $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||||
|
done; \
|
||||||
|
$(DOCKER) manifest push --purge $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION); \
|
||||||
done
|
done
|
||||||
$(DOCKER) manifest push --purge $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(VERSION)
|
|
||||||
|
|
||||||
push-all: build-all push
|
# We can't load the image into the local docker store, so we have to build and push it in one go
|
||||||
|
push-hostprocess:
|
||||||
|
set -x; \
|
||||||
|
for docker_repo in ${DOCKER_REPO}; do \
|
||||||
|
$(DOCKER) buildx build --push --build-arg=BASE=mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0 -f Dockerfile -t $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-hostprocess .; \
|
||||||
|
done
|
||||||
|
|
||||||
|
.PHONY: push-all
|
||||||
|
push-all: build-all
|
||||||
|
$(MAKE) DOCKER_REPO="$(ALL_DOCKER_REPOS)" push # push-hostprocess - disabled until it works on Windows
|
||||||
|
|
||||||
|
# Mandatory target for container description sync action
|
||||||
|
.PHONY: docker-repo-name
|
||||||
|
docker-repo-name:
|
||||||
|
@echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)"
|
||||||
|
|||||||
84
README.md
84
README.md
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
A Prometheus exporter for Windows machines.
|
A Prometheus exporter for Windows machines.
|
||||||
|
|
||||||
|
|
||||||
## Collectors
|
## Collectors
|
||||||
|
|
||||||
Name | Description | Enabled by default
|
Name | Description | Enabled by default
|
||||||
@@ -17,6 +16,7 @@ Name | Description | Enabled by default
|
|||||||
[cpu_info](docs/collector.cpu_info.md) | CPU Information |
|
[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 |
|
[container](docs/collector.container.md) | Container metrics |
|
||||||
|
[diskdrive](docs/collector.diskdrive.md) | Diskdrive metrics |
|
||||||
[dfsr](docs/collector.dfsr.md) | DFSR metrics |
|
[dfsr](docs/collector.dfsr.md) | DFSR metrics |
|
||||||
[dhcp](docs/collector.dhcp.md) | DHCP Server |
|
[dhcp](docs/collector.dhcp.md) | DHCP Server |
|
||||||
[dns](docs/collector.dns.md) | DNS Server |
|
[dns](docs/collector.dns.md) | DNS Server |
|
||||||
@@ -24,6 +24,7 @@ Name | Description | Enabled by default
|
|||||||
[fsrmquota](docs/collector.fsrmquota.md) | Microsoft File Server Resource Manager (FSRM) Quotas collector |
|
[fsrmquota](docs/collector.fsrmquota.md) | Microsoft File Server Resource Manager (FSRM) Quotas collector |
|
||||||
[hyperv](docs/collector.hyperv.md) | Hyper-V hosts |
|
[hyperv](docs/collector.hyperv.md) | Hyper-V hosts |
|
||||||
[iis](docs/collector.iis.md) | IIS sites and applications |
|
[iis](docs/collector.iis.md) | IIS sites and applications |
|
||||||
|
[license](docs/collector.license.md) | Windows license status |
|
||||||
[logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | ✓
|
[logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | ✓
|
||||||
[logon](docs/collector.logon.md) | User logon sessions |
|
[logon](docs/collector.logon.md) | User logon sessions |
|
||||||
[memory](docs/collector.memory.md) | Memory usage metrics |
|
[memory](docs/collector.memory.md) | Memory usage metrics |
|
||||||
@@ -44,11 +45,14 @@ Name | Description | Enabled by default
|
|||||||
[netframework_clrsecurity](docs/collector.netframework_clrsecurity.md) | .NET Framework Security Check metrics |
|
[netframework_clrsecurity](docs/collector.netframework_clrsecurity.md) | .NET Framework Security Check metrics |
|
||||||
[net](docs/collector.net.md) | Network interface I/O | ✓
|
[net](docs/collector.net.md) | Network interface I/O | ✓
|
||||||
[os](docs/collector.os.md) | OS metrics (memory, processes, users) | ✓
|
[os](docs/collector.os.md) | OS metrics (memory, processes, users) | ✓
|
||||||
|
[physical_disk](docs/collector.physical_disk.md) | physical disk metrics | ✓
|
||||||
|
[printer](docs/collector.printer.md) | Printer metrics |
|
||||||
[process](docs/collector.process.md) | Per-process metrics |
|
[process](docs/collector.process.md) | Per-process metrics |
|
||||||
[remote_fx](docs/collector.remote_fx.md) | RemoteFX protocol (RDP) metrics |
|
[remote_fx](docs/collector.remote_fx.md) | RemoteFX protocol (RDP) metrics |
|
||||||
[scheduled_task](docs/collector.scheduled_task.md) | Scheduled Tasks metrics |
|
[scheduled_task](docs/collector.scheduled_task.md) | Scheduled Tasks metrics |
|
||||||
[service](docs/collector.service.md) | Service state metrics | ✓
|
[service](docs/collector.service.md) | Service state metrics | ✓
|
||||||
[smb](docs/collector.smb.md) | SMB Server |
|
[smb](docs/collector.smb.md) | SMB Server |
|
||||||
|
[smbclient](docs/collector.smbclient.md) | SMB Client |
|
||||||
[smtp](docs/collector.smtp.md) | IIS SMTP Server |
|
[smtp](docs/collector.smtp.md) | IIS SMTP Server |
|
||||||
[system](docs/collector.system.md) | System calls | ✓
|
[system](docs/collector.system.md) | System calls | ✓
|
||||||
[tcp](docs/collector.tcp.md) | TCP connections |
|
[tcp](docs/collector.tcp.md) | TCP connections |
|
||||||
@@ -81,17 +85,17 @@ 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.
|
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
|
| Flag | Description | Default value |
|
||||||
---------|-------------|--------------------
|
|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
||||||
`--web.listen-address` | host:port for exporter. | `:9182`
|
| `--web.listen-address` | host:port for exporter. | `:9182` |
|
||||||
`--telemetry.path` | URL path for surfacing collected metrics. | `/metrics`
|
| `--telemetry.path` | URL path for surfacing collected metrics. | `/metrics` |
|
||||||
`--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5`
|
| `--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.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. |
|
| `--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`
|
| `--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
|
| `--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` | [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
|
| `--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false |
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
The latest release can be downloaded from the [releases page](https://github.com/prometheus-community/windows_exporter/releases).
|
The latest release can be downloaded from the [releases page](https://github.com/prometheus-community/windows_exporter/releases).
|
||||||
@@ -100,15 +104,17 @@ Each release provides a .msi installer. The installer will setup the windows_exp
|
|||||||
|
|
||||||
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. The following parameters are available:
|
||||||
|
|
||||||
Name | Description
|
| Name | Description |
|
||||||
-----|------------
|
|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
`ENABLED_COLLECTORS` | As the `--collectors.enabled` flag, provide a comma-separated list of enabled collectors
|
| `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 0.0.0.0
|
| `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.
|
| `LISTEN_PORT` | The port to bind to. Defaults to `9182`. |
|
||||||
`METRICS_PATH` | The path at which to serve metrics. Defaults to `/metrics`
|
| `METRICS_PATH` | The path at which to serve metrics. Defaults to `/metrics` |
|
||||||
`TEXTFILE_DIR` | As the `--collector.textfile.directory` flag, provide a directory to read text files with metrics from
|
| `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).
|
| `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.
|
| `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`. |
|
||||||
|
|
||||||
Parameters are sent to the installer via `msiexec`. Example invocations:
|
Parameters are sent to the installer via `msiexec`. Example invocations:
|
||||||
|
|
||||||
@@ -121,11 +127,25 @@ Example service collector with a custom query.
|
|||||||
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="--collector.service.services-where ""Name LIKE 'sql%'"""
|
||||||
```
|
```
|
||||||
|
|
||||||
On some older versions of Windows you may need to surround parameter values with double quotes to get the install command parsing properly:
|
On some older versions of Windows,
|
||||||
|
you may need to surround parameter values with double quotes to get the installation command parsing properly:
|
||||||
```powershell
|
```powershell
|
||||||
msiexec /i C:\Users\Administrator\Downloads\windows_exporter.msi ENABLED_COLLECTORS="ad,iis,logon,memory,process,tcp,textfile,thermalzone" TEXTFILE_DIR="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
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
```powershell
|
||||||
@@ -133,6 +153,20 @@ $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="--collector.service.services-where ""Name LIKE 'sql%'"""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Docker Implementation
|
||||||
|
|
||||||
|
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`
|
||||||
|
<!-- * [quay.io Registry](https://quay.io/repository/prometheuscommunity/windows-exporter): `quay.io/prometheuscommunity/windows-exporter` -->
|
||||||
|
|
||||||
|
### Tags
|
||||||
|
|
||||||
|
The Docker image is tagged with the version of the exporter. The `latest` tag is also available and points to the latest release.
|
||||||
|
|
||||||
|
Additionally, a flavor `hostprocess` with `-hostprocess` as suffix is based on the https://github.com/microsoft/windows-host-process-containers-base-image
|
||||||
|
which is designed to run as a Windows host process container. The size of that images is smaller than the default one.
|
||||||
|
|
||||||
## Kubernetes Implementation
|
## Kubernetes Implementation
|
||||||
|
|
||||||
@@ -140,7 +174,9 @@ See detailed steps to install on Windows Kubernetes [here](./kubernetes/kubernet
|
|||||||
|
|
||||||
## Supported versions
|
## Supported versions
|
||||||
|
|
||||||
windows_exporter supports Windows Server versions 2008R2 and later, and desktop Windows version 7 and later.
|
`windows_exporter` supports Windows Server versions 2016 and later, and desktop Windows version 10 and 11 (21H2 or later).
|
||||||
|
|
||||||
|
Windows Server 2012 and 2012R2 are supported as best-effort only, but not guaranteed to work.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Name | Description | Type | Labels
|
|||||||
`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_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_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_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 Privilged 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`
|
`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
|
### Example metric
|
||||||
Show frequency of host CPU cores
|
Show frequency of host CPU cores
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ None
|
|||||||
|
|
||||||
Name | Description | Type | Labels
|
Name | Description | Type | Labels
|
||||||
-----|-------------|------|-------
|
-----|-------------|------|-------
|
||||||
`windows_cpu_info` | Labeled CPU information | gauge | `architecture`, `device_id`, `description`, `family`, `l2_cache_size` `l3_cache_size`, `name`
|
`windows_cpu_info` | Labelled CPU information | gauge | `architecture`, `device_id`, `description`, `family`, `l2_cache_size` `l3_cache_size`, `name`
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Name | Description | Type | Labels
|
|||||||
-----|-------------|------|-------
|
-----|-------------|------|-------
|
||||||
`windows_cs_logical_processors` | Number of installed logical processors | gauge | None
|
`windows_cs_logical_processors` | Number of installed logical processors | gauge | None
|
||||||
`windows_cs_physical_memory_bytes` | Total installed physical memory | gauge | None
|
`windows_cs_physical_memory_bytes` | Total installed physical memory | gauge | None
|
||||||
`windows_cs_hostname` | Labeled system hostname information | gauge | `hostname`, `domain`, `fqdn`
|
`windows_cs_hostname` | Labelled system hostname information | gauge | `hostname`, `domain`, `fqdn`
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ The diskdrive collector exposes metrics about physical disks
|
|||||||
| | |
|
| | |
|
||||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| Metric name prefix | `diskdrive` |
|
| Metric name prefix | `diskdrive` |
|
||||||
| Classes | [`Win32_PerfRawData_DNS_DNS`](https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrive) |
|
| Classes | [`Win32_DiskDrive`](https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrive) |
|
||||||
| Enabled by default? | No |
|
| Enabled by default? | No |
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
@@ -16,11 +16,11 @@ None
|
|||||||
|
|
||||||
| Name | Description | Type | Labels |
|
| Name | Description | Type | Labels |
|
||||||
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ |
|
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ |
|
||||||
| `disk_drive_info` | General identifiable information about the disk drive | gauge | name,caption,device_id,model |
|
| `diskdrive_info` | General identifiable information about the disk drive | gauge | name,caption,device_id,model |
|
||||||
| `disk_drive_availability` | The disk drive's current availability | gauge | name,availability |
|
| `diskdrive_availability` | The disk drive's current availability | gauge | name,availability |
|
||||||
| `disk_drive_partitions` | Number of partitions on the drive | gauge | name |
|
| `diskdrive_partitions` | Number of partitions on the drive | gauge | name |
|
||||||
| `disk_drive_size` | Size of the disk drive. It is calculated by multiplying the total number of cylinders, tracks in each cylinder, sectors in each track, and bytes in each sector. | gauge | name |
|
| `diskdrive_size` | Size of the disk drive. It is calculated by multiplying the total number of cylinders, tracks in each cylinder, sectors in each track, and bytes in each sector. | gauge | name |
|
||||||
| `disk_drive_status` | Operational status of the drive | gauge | name,status |
|
| `diskdrive_status` | Operational status of the drive | gauge | name,status |
|
||||||
|
|
||||||
## Alerting examples
|
## Alerting examples
|
||||||
**prometheus.rules**
|
**prometheus.rules**
|
||||||
|
|||||||
53
docs/collector.license.md
Normal file
53
docs/collector.license.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# license collector
|
||||||
|
|
||||||
|
The license collector exposes metrics about the Windows license status.
|
||||||
|
|
||||||
|
|||
|
||||||
|
-|-
|
||||||
|
Metric name prefix | `license`
|
||||||
|
Data source | Win32
|
||||||
|
Enabled by default? | No
|
||||||
|
|
||||||
|
## Flags
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
## Metrics
|
||||||
|
|
||||||
|
| Name | Description | Type | Labels |
|
||||||
|
|--------------------------|----------------|-------|---------|
|
||||||
|
| `windows_license_status` | license status | gauge | `state` |
|
||||||
|
|
||||||
|
### Example metric
|
||||||
|
|
||||||
|
```
|
||||||
|
# HELP windows_license_status Status of windows license
|
||||||
|
# TYPE windows_license_status gauge
|
||||||
|
windows_license_status{state="genuine"} 1
|
||||||
|
windows_license_status{state="invalid_license"} 0
|
||||||
|
windows_license_status{state="last"} 0
|
||||||
|
windows_license_status{state="offline"} 0
|
||||||
|
windows_license_status{state="tampered"} 0
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Useful queries
|
||||||
|
|
||||||
|
Show if the license is genuine
|
||||||
|
|
||||||
|
```
|
||||||
|
windows_license_status{state="genuine"}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Alerting examples
|
||||||
|
**prometheus.rules**
|
||||||
|
```yaml
|
||||||
|
- alert: "WindowsLicense"
|
||||||
|
expr: 'windows_license_status{state="genuine"} == 0'
|
||||||
|
for: "10m"
|
||||||
|
labels:
|
||||||
|
severity: "high"
|
||||||
|
annotations:
|
||||||
|
summary: "Windows system license is not genuine"
|
||||||
|
description: "The Windows system license is not genuine. Please check the license status."
|
||||||
|
```
|
||||||
@@ -23,6 +23,7 @@ If given, a disk needs to *not* match the exclude regexp in order for the corres
|
|||||||
|
|
||||||
Name | Description | Type | Labels
|
Name | Description | Type | Labels
|
||||||
-----|-------------|------|-------
|
-----|-------------|------|-------
|
||||||
|
`windows_logical_disk_info` | A metric with a constant '1' value labeled with logical disk information | gauge | `disk`,`filesystem`,`serial_number`,`volume`,`volume_name`,`type`
|
||||||
`windows_logical_disk_requests_queued` | Number of requests outstanding on the disk at the time the performance data is collected | gauge | `volume`
|
`windows_logical_disk_requests_queued` | Number of requests outstanding on the disk at the time the performance data is collected | gauge | `volume`
|
||||||
`windows_logical_disk_avg_read_requests_queued` | Average number of read requests that were queued for the selected disk during the sample interval | gauge | `volume`
|
`windows_logical_disk_avg_read_requests_queued` | Average number of read requests that were queued for the selected disk during the sample interval | gauge | `volume`
|
||||||
`windows_logical_disk_avg_write_requests_queued` | Average number of write requests that were queued for the selected disk during the sample interval | gauge | `volume`
|
`windows_logical_disk_avg_write_requests_queued` | Average number of write requests that were queued for the selected disk during the sample interval | gauge | `volume`
|
||||||
@@ -36,6 +37,7 @@ Name | Description | Type | Labels
|
|||||||
`windows_logical_disk_size_bytes` | Total size of the disk in bytes (not real time, updates every 10-15 min) | gauge | `volume`
|
`windows_logical_disk_size_bytes` | Total size of the disk in bytes (not real time, updates every 10-15 min) | gauge | `volume`
|
||||||
`windows_logical_disk_idle_seconds_total` | Seconds the disk was idle (not servicing read/write requests) | counter | `volume`
|
`windows_logical_disk_idle_seconds_total` | Seconds the disk was idle (not servicing read/write requests) | counter | `volume`
|
||||||
`windows_logical_disk_split_ios_total` | Number of I/Os to the disk split into multiple I/Os | counter | `volume`
|
`windows_logical_disk_split_ios_total` | Number of I/Os to the disk split into multiple I/Os | counter | `volume`
|
||||||
|
`windows_logical_disk_readonly` | Whether the logical disk is read-only | gauge | `volume`
|
||||||
|
|
||||||
### Warning about size metrics
|
### Warning about size metrics
|
||||||
The `free_bytes` and `size_bytes` metrics are not updated in real time and might have a delay of 10-15min.
|
The `free_bytes` and `size_bytes` metrics are not updated in real time and might have a delay of 10-15min.
|
||||||
@@ -47,6 +49,15 @@ Query the rate of write operations to a disk
|
|||||||
rate(windows_logical_disk_read_bytes_total{instance="localhost", volume=~"C:"}[2m])
|
rate(windows_logical_disk_read_bytes_total{instance="localhost", volume=~"C:"}[2m])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Logical Volume information
|
||||||
|
```
|
||||||
|
windows_logical_disk_info{disk_id="0",filesystem="",serial_number="",type="",volume="HarddiskVolume2",volume_name=""} 1
|
||||||
|
windows_logical_disk_info{disk_id="0",filesystem="",serial_number="",type="",volume="HarddiskVolume3",volume_name=""} 1
|
||||||
|
windows_logical_disk_info{disk_id="0",filesystem="NTFS",serial_number="668EEC37",type="fixed",volume="C:",volume_name="Windows"} 1
|
||||||
|
windows_logical_disk_info{disk_id="1",filesystem="NTFS",serial_number="50AE953B",type="fixed",volume="D:",volume_name="Temporary Storage"} 1
|
||||||
|
windows_logical_disk_info{disk_id="1",filesystem="ReFS",serial_number="C69B59AD",type="fixed",volume="G:",volume_name="Volume"} 1
|
||||||
|
```
|
||||||
|
|
||||||
## Useful queries
|
## Useful queries
|
||||||
Calculate rate of total IOPS for disk
|
Calculate rate of total IOPS for disk
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Name | Description | Type | Labels
|
|||||||
`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`
|
`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`
|
`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`
|
`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`
|
`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`
|
`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`
|
`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`
|
||||||
@@ -34,10 +35,16 @@ Name | Description | Type | Labels
|
|||||||
`Subclass` | Provides the list of references to nodes that can be the owner of this resource. | 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
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
Query the state of all cluster resource owned by node1
|
||||||
|
```
|
||||||
|
windows_mscluster_resource_owner_node{node_name="node1"}
|
||||||
|
```
|
||||||
|
|
||||||
## Useful queries
|
## Useful queries
|
||||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
Counts the number of Network Name cluster resource
|
||||||
|
```
|
||||||
|
count(windows_mscluster_resource_state{type="Network Name"})
|
||||||
|
```
|
||||||
|
|
||||||
## Alerting examples
|
## Alerting examples
|
||||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||||
|
|||||||
@@ -26,16 +26,23 @@ Name | Description | Type | Labels
|
|||||||
`FailoverThreshold` | The FailoverThreshold property specifies the maximum number of failover attempts. | 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`
|
`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`
|
`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`
|
`Priority` | Priority value of the resource group | gauge | `name`
|
||||||
`ResiliencyPeriod` | The resiliency period for this group, in seconds. | 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`
|
`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`
|
`UpdateDomain` | | gauge | `name`
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
Query the state of all cluster group owned by node1
|
||||||
|
```
|
||||||
|
windows_mscluster_resourcegroup_owner_node{node_name="node1"}
|
||||||
|
```
|
||||||
|
|
||||||
## Useful queries
|
## Useful queries
|
||||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
Counts the number of cluster group by type
|
||||||
|
```
|
||||||
|
count_values("count", windows_mscluster_resourcegroup_group_type)
|
||||||
|
```
|
||||||
|
|
||||||
## Alerting examples
|
## Alerting examples
|
||||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||||
|
|||||||
@@ -258,10 +258,23 @@ Name | Description | Type | Labels
|
|||||||
`windows_mssql_waitstats_transaction_ownership_waits` | Statistics relevant to processes synchronizing access to transaction | gauge | `mssql_instance`, `item`
|
`windows_mssql_waitstats_transaction_ownership_waits` | Statistics relevant to processes synchronizing access to transaction | gauge | `mssql_instance`, `item`
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
|
||||||
|
|
||||||
|
Query Full table scans
|
||||||
|
|
||||||
|
```
|
||||||
|
rate(windows_mssql_accessmethods_full_scans{instance='host:9182'}[$__rate_interval])
|
||||||
|
|
||||||
|
```
|
||||||
## Useful queries
|
## Useful queries
|
||||||
|
|
||||||
|
### Database file size
|
||||||
|
This collector retrieves the two values (data file and log file) and sums the total in PromQL to give the Database file size.
|
||||||
|
|
||||||
|
```
|
||||||
|
windows_mssql_databases_data_files_size_bytes{database='DatabaseName',instance='host:9182'} + windows_mssql_databases_log_files_size_bytes{database='DatabaseName',instance='host:9182'}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
### Buffer Cache Hit Ratio
|
### Buffer Cache Hit Ratio
|
||||||
|
|
||||||
When you read the counter in perfmon you will get the the percentage pages found in the buffer cache. This percentage is calculated internally based on the total number of cache hits divided by the total number of cache lookups over the last few thousand page accesses.
|
When you read the counter in perfmon you will get the the percentage pages found in the buffer cache. This percentage is calculated internally based on the total number of cache hits divided by the total number of cache lookups over the last few thousand page accesses.
|
||||||
@@ -284,4 +297,18 @@ This principal can be used for following metrics too:
|
|||||||
- locks_count
|
- locks_count
|
||||||
|
|
||||||
## Alerting examples
|
## Alerting examples
|
||||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
|
||||||
|
```
|
||||||
|
groups:
|
||||||
|
- name: database_alerts
|
||||||
|
rules:
|
||||||
|
- alert: DatabaseSizeExceeded
|
||||||
|
expr: windows_mssql_databases_data_files_size_bytes{database='DatabaseName',instance='host:9182'} + windows_mssql_databases_log_files_size_bytes{database='DatabaseName',instance='host:9182'} > 1e10 # 10 GB in bytes
|
||||||
|
for: 5m # Trigger the alert if the condition persists for 5 mins
|
||||||
|
labels:
|
||||||
|
severity: critical
|
||||||
|
annotations:
|
||||||
|
summary: "SQl EXpress Database size exceeded 10GB"
|
||||||
|
description: "The database size has grown larger than 10GB. Instance: {{ $labels.instance }}"
|
||||||
|
|
||||||
|
```
|
||||||
28
docs/collector.printer.md
Normal file
28
docs/collector.printer.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# printer collector
|
||||||
|
|
||||||
|
The printer collector exposes metrics about printers and their jobs.
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| Metric name prefix | `printer` |
|
||||||
|
| Data source | WMI |
|
||||||
|
| Classes | [Win32_Printer](https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-printer) <br> [Win32_PrintJob](https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-printjob) |
|
||||||
|
| Enabled by default? | false |
|
||||||
|
|
||||||
|
## Flags
|
||||||
|
|
||||||
|
### `--collector.printer.include`
|
||||||
|
|
||||||
|
If given, a printer needs to match the include regexp in order for the corresponding printer metrics to be reported
|
||||||
|
|
||||||
|
### `--collector.printer.exclude`
|
||||||
|
|
||||||
|
If given, a printer needs to *not* match the exclude regexp in order for the corresponding printer metrics to be reported
|
||||||
|
|
||||||
|
## Metrics
|
||||||
|
|
||||||
|
Name | Description | Type | Labels
|
||||||
|
-----|-------------|---------|-------
|
||||||
|
`windows_printer_status` | Status of the printer at the time the performance data is collected | counter | `printer`, `status`
|
||||||
|
`windows_printer_job_count` | Number of jobs processed by the printer since the last reset | gauge | `printer`
|
||||||
|
`windows_printer_job_status` | A counter of printer jobs by status | gauge | `printer`, `status`
|
||||||
@@ -2,16 +2,23 @@
|
|||||||
|
|
||||||
The process collector exposes metrics about processes.
|
The process collector exposes metrics about processes.
|
||||||
|
|
||||||
|||
|
Note, on Windows Server 2022, the `Process` counter set is disabled by default. To enable it, run the following command in an elevated PowerShell session:
|
||||||
-|-
|
|
||||||
Metric name prefix | `process`
|
```powershell
|
||||||
Data source | Perflib
|
lodctr.exe /E:Lsa
|
||||||
Counters | `Process`
|
lodctr.exe /E:PerfProc
|
||||||
Enabled by default? | No
|
lodctr.exe /R
|
||||||
|
```
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---------------------|-----------|
|
||||||
|
| Metric name prefix | `process` |
|
||||||
|
| Data source | Perflib |
|
||||||
|
| Counters | `Process` |
|
||||||
|
| Enabled by default? | No |
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
### `--collector.process.include`
|
### `--collector.process.include`
|
||||||
|
|
||||||
Regexp of processes to include. Process name must both match `include` and not
|
Regexp of processes to include. Process name must both match `include` and not
|
||||||
@@ -30,6 +37,12 @@ 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`.
|
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
|
### Example
|
||||||
To match all firefox processes: `--collector.process.include="firefox.*"`.
|
To match all firefox processes: `--collector.process.include="firefox.*"`.
|
||||||
Note that multiple processes with the same name will be disambiguated by
|
Note that multiple processes with the same name will be disambiguated by
|
||||||
@@ -61,23 +74,23 @@ w3wp_Test
|
|||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
Name | Description | Type | Labels
|
| Name | Description | Type | Labels |
|
||||||
-----|-------------|------|-------
|
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------------------------------------------------------|
|
||||||
`windows_process_start_time` | Time of process start | gauge | `process`, `process_id`, `creating_process_id`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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`
|
| `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` |
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||||
|
|||||||
@@ -24,10 +24,15 @@ Name | Description | Type | Labels
|
|||||||
`windows_remote_fx_net_current_tcp_rtt_seconds` | Average TCP round-trip time (RTT) detected in seconds. | gauge | `session_name`
|
`windows_remote_fx_net_current_tcp_rtt_seconds` | Average TCP round-trip time (RTT) detected in seconds. | gauge | `session_name`
|
||||||
`windows_remote_fx_net_current_udp_bandwidth` | UDP Bandwidth detected in bytes per second. | gauge | `session_name`
|
`windows_remote_fx_net_current_udp_bandwidth` | UDP Bandwidth detected in bytes per second. | gauge | `session_name`
|
||||||
`windows_remote_fx_net_current_udp_rtt_seconds` | Average UDP round-trip time (RTT) detected in seconds. | gauge | `session_name`
|
`windows_remote_fx_net_current_udp_rtt_seconds` | Average UDP round-trip time (RTT) detected in seconds. | gauge | `session_name`
|
||||||
`windows_remote_fx_net_received_bytes_total` | _Not yet documented_ | counter | `session_name`
|
`windows_remote_fx_net_received_bytes_total` | Total bytes received over the network session. | counter | `session_name`
|
||||||
`windows_remote_fx_net_sent_bytes_total` | _Not yet documented_ | counter | `session_name`
|
`windows_remote_fx_net_sent_bytes_total` | Total bytes sent over the network session. | counter | `session_name`
|
||||||
`windows_remote_fx_net_udp_packets_received_total` | Rate in packets per second at which packets are received over UDP. | counter | `session_name`
|
`windows_remote_fx_net_udp_packets_received_total` | Rate in packets per second at which packets are received over UDP. | counter | `session_name`
|
||||||
`windows_remote_fx_net_udp_packets_sent_total` | Rate in packets per second at which packets are sent over UDP. | counter | `session_name`
|
`windows_remote_fx_net_udp_packets_sent_total` | Rate in packets per second at which packets are sent over UDP. | counter | `session_name`
|
||||||
|
`windows_remote_fx_net_loss_rate` | Network packet loss rate detected over the RemoteFX session, expressed as a percentage. | counter | `session_name`
|
||||||
|
`windows_remote_fx_net_fec_rate` | Forward Error Correction (FEC) rate applied to packets sent over the RemoteFX session, expressed as a percentage. | counter | `session_name`
|
||||||
|
`windows_remote_fx_net_retransmission_rate` Rate of packets retransmitted over the RemoteFX session, expressed as a percentage. | counter | `session_name`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Metrics (Graphics)
|
## Metrics (Graphics)
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
The service collector exposes metrics about Windows Services
|
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
|
||||||
Metric name prefix | `service`
|
provide additional information like `run_as` or start configuration
|
||||||
Classes | [`Win32_Service`](https://msdn.microsoft.com/en-us/library/aa394418(v=vs.85).aspx)
|
|
||||||
Enabled by default? | Yes
|
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
@@ -22,6 +20,19 @@ Example config win_exporter.yml for multiple services: `services-where: Name='SQ
|
|||||||
|
|
||||||
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.
|
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)
|
||||||
|
Enabled by default? | Yes
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
Name | Description | Type | Labels
|
Name | Description | Type | Labels
|
||||||
@@ -91,6 +102,53 @@ Counts the number of Microsoft SQL Server/Agent Processes
|
|||||||
count(windows_service_state{exported_name=~"(sqlserveragent|mssqlserver)",state="running"})
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
## Useful queries
|
||||||
|
Counts the number of Microsoft SQL Server/Agent Processes
|
||||||
|
|
||||||
|
```
|
||||||
|
count(windows_service_state{name=~"(sqlserveragent|mssqlserver)",state="running"})
|
||||||
|
```
|
||||||
|
|
||||||
## Alerting examples
|
## Alerting examples
|
||||||
**prometheus.rules**
|
**prometheus.rules**
|
||||||
```yaml
|
```yaml
|
||||||
@@ -100,7 +158,7 @@ groups:
|
|||||||
|
|
||||||
# Sends an alert when the 'sqlserveragent' service is not in the running state for 3 minutes.
|
# Sends an alert when the 'sqlserveragent' service is not in the running state for 3 minutes.
|
||||||
- alert: SQL Server Agent DOWN
|
- alert: SQL Server Agent DOWN
|
||||||
expr: windows_service_state{instance="SQL",exported_name="sqlserveragent",state="running"} == 0
|
expr: windows_service_state{instance="SQL",name="sqlserveragent",state="running"} == 0
|
||||||
for: 3m
|
for: 3m
|
||||||
labels:
|
labels:
|
||||||
severity: high
|
severity: high
|
||||||
@@ -110,7 +168,7 @@ groups:
|
|||||||
|
|
||||||
# Sends an alert when the 'mssqlserver' service is not in the running state for 3 minutes.
|
# Sends an alert when the 'mssqlserver' service is not in the running state for 3 minutes.
|
||||||
- alert: SQL Server DOWN
|
- alert: SQL Server DOWN
|
||||||
expr: windows_service_state{instance="SQL",exported_name="mssqlserver",state="running"} == 0
|
expr: windows_service_state{instance="SQL",name="mssqlserver",state="running"} == 0
|
||||||
for: 3m
|
for: 3m
|
||||||
labels:
|
labels:
|
||||||
severity: high
|
severity: high
|
||||||
|
|||||||
50
docs/collector.smbclient.md
Normal file
50
docs/collector.smbclient.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# smbclient collector
|
||||||
|
The smbclient collector collects metrics from MS SmbClient hosts through perflib
|
||||||
|
|||
|
||||||
|
-|-
|
||||||
|
Metric name prefix | `windows_smbclient`
|
||||||
|
Classes | [Win32_PerfRawData_SMB](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/)<br/>
|
||||||
|
Enabled by default? | No
|
||||||
|
|
||||||
|
## Flags
|
||||||
|
|
||||||
|
### `--collectors.smbclient.list`
|
||||||
|
Lists the Perflib Objects that are queried for data along with the perlfib object id
|
||||||
|
|
||||||
|
### `--collectors.smbclient.enabled`
|
||||||
|
Comma-separated list of collectors to use, for example: `--collectors.smbclient.enabled=ServerShares`. Matching is case-sensitive. Depending on the smb protocol version not all performance counters may be available. Use `--collectors.smbclient.list` to obtain a list of supported collectors.
|
||||||
|
|
||||||
|
## Metrics
|
||||||
|
Name | Description | Type | Labels
|
||||||
|
-----|-------------|------|-------
|
||||||
|
`windows_smbclient_data_queue_seconds_total` | Seconds requests waited on queue on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_read_queue_seconds_total` | Seconds read requests waited on queue on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_write_queue_seconds_total` | Seconds write requests waited on queue on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_request_seconds_total` | Seconds waiting for requests on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_stalls_total` | The number of requests delayed based on insufficient credits on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_requests_queued` | The point in time (current) number of requests outstanding on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_data_bytes_total` | The bytes read or written on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_requests_total` | The requests on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_metadata_requests_total` | The metadata requests on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_read_bytes_via_smbdirect_total` | The bytes read from this share via RDMA direct placement | TBD | `server`, `share`|
|
||||||
|
`windows_smbclient_read_bytes_total` | The bytes read on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_read_requests_via_smbdirect_total` | The read requests on this share via RDMA direct placement | TBD | `server`, `share`|
|
||||||
|
`windows_smbclient_read_requests_total` | The read requests on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_turbo_io_reads_total` | The read requests that go through Turbo I/O | TBD | `server`, `share`|
|
||||||
|
`windows_smbclient_turbo_io_writes_total` | The write requests that go through Turbo I/O | TBD | `server`, `share`|
|
||||||
|
`windows_smbclient_write_bytes_via_smbdirect_total` | The written bytes to this share via RDMA direct placement | TBD | `server`, `share`|
|
||||||
|
`windows_smbclient_write_bytes_total` | The bytes written on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_write_requests_via_smbdirect_total` | The write requests to this share via RDMA direct placement | TBD | `server`, `share`|
|
||||||
|
`windows_smbclient_write_requests_total` | The write requests on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_read_seconds_total` | Seconds waiting for read requests on this share | counter | `server`, `share`|
|
||||||
|
`windows_smbclient_write_seconds_total` | Seconds waiting for write requests on this share | counter | `server`, `share`|
|
||||||
|
## Useful queries
|
||||||
|
```
|
||||||
|
# Average request queue length (includes read and write).
|
||||||
|
irate(windows_smbclient_data_queue_seconds_total)
|
||||||
|
# Request latency milliseconds (includes read and write).
|
||||||
|
irate(windows_smbclient_request_seconds_total) / irate(windows_smbclient_requests_total) * 1000
|
||||||
|
```
|
||||||
|
## Alerting examples
|
||||||
|
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||||
|
|
||||||
@@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
The terminal_services collector exposes terminal services (Remote Desktop Services) performance metrics.
|
The terminal_services collector exposes terminal services (Remote Desktop Services) performance metrics.
|
||||||
|
|
||||||
|||
|
| | |
|
||||||
-|-
|
|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
Metric name prefix | `terminal_services`
|
| __Metric name prefix__ | `terminal_services` |
|
||||||
Data source | Perflib/WMI
|
| __Data source__ | Perflib/WMI, Win32 |
|
||||||
Classes | [`Win32_PerfRawData_LocalSessionManager_TerminalServices`](https://wutils.com/wmi/root/cimv2/win32_perfrawdata_localsessionmanager_terminalservices/), [`Win32_PerfRawData_TermService_TerminalServicesSession`](https://docs.microsoft.com/en-us/previous-versions/aa394344(v%3Dvs.85)), [`Win32_PerfRawData_RemoteDesktopConnectionBrokerPerformanceCounterProvider_RemoteDesktopConnectionBrokerCounterset`](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/mt729067(v%3Dws.11))
|
| __Classes__ | [`Win32_PerfRawData_LocalSessionManager_TerminalServices`](https://wutils.com/wmi/root/cimv2/win32_perfrawdata_localsessionmanager_terminalservices/), [`Win32_PerfRawData_TermService_TerminalServicesSession`](https://docs.microsoft.com/en-us/previous-versions/aa394344(v%3Dvs.85)), [`Win32_PerfRawData_RemoteDesktopConnectionBrokerPerformanceCounterProvider_RemoteDesktopConnectionBrokerCounterset`](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/mt729067(v%3Dws.11)) |
|
||||||
Enabled by default? | No
|
| __Win32 API__ | [WTSEnumerateSessionsEx](https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsenumeratesessionsexw) |
|
||||||
|
| __Enabled by default?__ | No |
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
@@ -15,34 +16,116 @@ None
|
|||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
Name | Description | Type | Labels
|
| Name | Description | Type | Labels |
|
||||||
-----|-------------|------|-------
|
|------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------|
|
||||||
`windows_terminal_services_local_session_count` | Number of local Terminal Services sessions. | gauge | `session`
|
| `windows_terminal_services_session_info` | Info about active WTS sessions | gauge | host,user,state |
|
||||||
`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_local_session_count` | Number of local Terminal Services sessions. | gauge | `session` |
|
||||||
`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_connection_broker_performance_total`* | The total number of connections handled by the Connection Brokers since the service started. | counter | `connection` |
|
||||||
`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`
|
| `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_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 | `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` |
|
||||||
`windows_terminal_services_page_file_bytes_peak` | Maximum 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 | `session_name`
|
| `windows_terminal_services_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 | `session_name` |
|
||||||
`windows_terminal_services_privileged_time_seconds_total` | total elapsed time that the threads of the process have spent executing code in privileged mode. | Counter | `session_name`
|
| `windows_terminal_services_page_file_bytes_peak` | Maximum 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 | `session_name` |
|
||||||
`windows_terminal_services_processor_time_seconds_total` | total elapsed time that all of the threads of this process used the processor to execute instructions. | Counter | `session_name`
|
| `windows_terminal_services_privileged_time_seconds_total` | total elapsed time that the threads of the process have spent executing code in privileged mode. | Counter | `session_name` |
|
||||||
`windows_terminal_services_user_time_seconds_total` | total elapsed time that this process's threads have spent executing code in user mode. Applications, environment subsystems, and integral subsystems execute in user mode. | Counter | `session_name`
|
| `windows_terminal_services_processor_time_seconds_total` | total elapsed time that all of the threads of this process used the processor to execute instructions. | Counter | `session_name` |
|
||||||
`windows_terminal_services_pool_non_paged_bytes` | Number of bytes in the non-paged pool, 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. This property displays the last observed value only; it is not an average. | gauge | `session_name`
|
| `windows_terminal_services_user_time_seconds_total` | total elapsed time that this process's threads have spent executing code in user mode. Applications, environment subsystems, and integral subsystems execute in user mode. | Counter | `session_name` |
|
||||||
`windows_terminal_services_pool_paged_bytes` | Number of bytes in the paged pool, 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. This property displays the last observed value only; it is not an average. | gauge | `session_name`
|
| `windows_terminal_services_pool_non_paged_bytes` | Number of bytes in the non-paged pool, 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. This property displays the last observed value only; it is not an average. | gauge | `session_name` |
|
||||||
`windows_terminal_services_private_bytes` | Current number of bytes this process has allocated that cannot be shared with other processes. | gauge | `session_name`
|
| `windows_terminal_services_pool_paged_bytes` | Number of bytes in the paged pool, 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. This property displays the last observed value only; it is not an average. | gauge | `session_name` |
|
||||||
`windows_terminal_services_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 | `session_name`
|
| `windows_terminal_services_private_bytes` | Current number of bytes this process has allocated that cannot be shared with other processes. | gauge | `session_name` |
|
||||||
`windows_terminal_services_virtual_bytes` | Current size, in bytes, of the virtual address space 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 | `session_name`
|
| `windows_terminal_services_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 | `session_name` |
|
||||||
`windows_terminal_services_virtual_bytes_peak` | Maximum number of bytes of virtual address space the process has used at any one time. 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 might limit its ability to load libraries. | gauge | `session_name`
|
| `windows_terminal_services_virtual_bytes` | Current size, in bytes, of the virtual address space 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 | `session_name` |
|
||||||
`windows_terminal_services_working_set_bytes` | Current number of bytes in the working set of this process. 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 | `session_name`
|
| `windows_terminal_services_virtual_bytes_peak` | Maximum number of bytes of virtual address space the process has used at any one time. 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 might limit its ability to load libraries. | gauge | `session_name` |
|
||||||
`windows_terminal_services_working_set_bytes_peak` | 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 | `session_name`
|
| `windows_terminal_services_working_set_bytes` | Current number of bytes in the working set of this process. 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 | `session_name` |
|
||||||
|
| `windows_terminal_services_working_set_bytes_peak` | 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 | `session_name` |
|
||||||
|
|
||||||
`* windows_terminal_services_connection_broker_performance_total` only collected if server has `Remote Desktop Connection Broker` role.
|
`* windows_terminal_services_connection_broker_performance_total` only collected if server has `Remote Desktop Connection Broker` role.
|
||||||
|
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
|
||||||
|
```
|
||||||
|
windows_remote_fx_net_udp_packets_sent_total{session_name="RDP-Tcp 0"} 0
|
||||||
|
# HELP windows_terminal_services_cpu_time_seconds_total Total elapsed time that this process's threads have spent executing code.
|
||||||
|
# TYPE windows_terminal_services_cpu_time_seconds_total counter
|
||||||
|
windows_terminal_services_cpu_time_seconds_total{mode="RDP-Tcp 0",session_name="privileged"} 98.4843739
|
||||||
|
windows_terminal_services_cpu_time_seconds_total{mode="RDP-Tcp 0",session_name="processor"} 620.4687488999999
|
||||||
|
windows_terminal_services_cpu_time_seconds_total{mode="RDP-Tcp 0",session_name="user"} 521.9843741
|
||||||
|
# HELP 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.
|
||||||
|
# TYPE windows_terminal_services_handles gauge
|
||||||
|
windows_terminal_services_handles{session_name="RDP-Tcp 0"} 20999
|
||||||
|
# HELP 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.
|
||||||
|
# TYPE windows_terminal_services_page_fault_total counter
|
||||||
|
windows_terminal_services_page_fault_total{session_name="RDP-Tcp 0"} 1.0436271e+07
|
||||||
|
# HELP windows_terminal_services_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.
|
||||||
|
# TYPE windows_terminal_services_page_file_bytes gauge
|
||||||
|
windows_terminal_services_page_file_bytes{session_name="RDP-Tcp 0"} 4.310188032e+09
|
||||||
|
# HELP windows_terminal_services_page_file_bytes_peak Maximum 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.
|
||||||
|
# TYPE windows_terminal_services_page_file_bytes_peak gauge
|
||||||
|
windows_terminal_services_page_file_bytes_peak{session_name="RDP-Tcp 0"} 4.817412096e+09
|
||||||
|
# HELP windows_terminal_services_pool_non_paged_bytes Number of bytes in the non-paged pool, 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. This property displays the last observed value only; it is not an average.
|
||||||
|
# TYPE windows_terminal_services_pool_non_paged_bytes gauge
|
||||||
|
windows_terminal_services_pool_non_paged_bytes{session_name="RDP-Tcp 0"} 1.325456e+06
|
||||||
|
# HELP windows_terminal_services_pool_paged_bytes Number of bytes in the paged pool, 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. This property displays the last observed value only; it is not an average.
|
||||||
|
# TYPE windows_terminal_services_pool_paged_bytes gauge
|
||||||
|
windows_terminal_services_pool_paged_bytes{session_name="RDP-Tcp 0"} 2.4651264e+07
|
||||||
|
# HELP windows_terminal_services_private_bytes Current number of bytes this process has allocated that cannot be shared with other processes.
|
||||||
|
# TYPE windows_terminal_services_private_bytes gauge
|
||||||
|
windows_terminal_services_private_bytes{session_name="RDP-Tcp 0"} 4.310188032e+09
|
||||||
|
# HELP windows_terminal_services_session_info Terminal Services sessions info
|
||||||
|
# TYPE windows_terminal_services_session_info gauge
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="active",user="domain\\user"} 1
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="connect_query",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="connected",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="disconnected",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="down",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="idle",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="init",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="listen",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="reset",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="RDP-Tcp 0",state="shadow",user="domain\\user"} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="active",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="connect_query",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="connected",user=""} 1
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="disconnected",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="down",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="idle",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="init",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="listen",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="reset",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="console",state="shadow",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="active",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="connect_query",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="connected",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="disconnected",user=""} 1
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="down",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="idle",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="init",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="listen",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="reset",user=""} 0
|
||||||
|
windows_terminal_services_session_info{host="",session_name="services",state="shadow",user=""} 0
|
||||||
|
# HELP windows_terminal_services_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.
|
||||||
|
# TYPE windows_terminal_services_threads gauge
|
||||||
|
windows_terminal_services_threads{session_name="RDP-Tcp 0"} 676
|
||||||
|
# HELP windows_terminal_services_virtual_bytes Current size, in bytes, of the virtual address space 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.
|
||||||
|
# TYPE windows_terminal_services_virtual_bytes gauge
|
||||||
|
windows_terminal_services_virtual_bytes{session_name="RDP-Tcp 0"} 9.3228347629568e+13
|
||||||
|
# HELP windows_terminal_services_virtual_bytes_peak Maximum number of bytes of virtual address space the process has used at any one time. 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 might limit its ability to load libraries.
|
||||||
|
# TYPE windows_terminal_services_virtual_bytes_peak gauge
|
||||||
|
windows_terminal_services_virtual_bytes_peak{session_name="RDP-Tcp 0"} 9.323192164352e+13
|
||||||
|
# HELP windows_terminal_services_working_set_bytes Current number of bytes in the working set of this process. 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.
|
||||||
|
# TYPE windows_terminal_services_working_set_bytes gauge
|
||||||
|
windows_terminal_services_working_set_bytes{session_name="RDP-Tcp 0"} 6.0632064e+09
|
||||||
|
# HELP windows_terminal_services_working_set_bytes_peak 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.
|
||||||
|
# TYPE windows_terminal_services_working_set_bytes_peak gauge
|
||||||
|
windows_terminal_services_working_set_bytes_peak{session_name="RDP-Tcp 0"} 6.74854912e+09
|
||||||
|
```
|
||||||
|
|
||||||
## Useful queries
|
## Useful queries
|
||||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
|
||||||
|
Use metrics can be combined with other metrics to create useful queries. For example, with remote_fx metrics:
|
||||||
|
|
||||||
|
```
|
||||||
|
windows_remote_fx_net_loss_rate * on(session_name) group_left(user) (windows_terminal_services_session_info == 1)
|
||||||
|
```
|
||||||
|
|
||||||
## Alerting examples
|
## Alerting examples
|
||||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||||
|
|||||||
101
exporter.go
101
exporter.go
@@ -1,20 +1,23 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
|
|
||||||
|
//go:generate go run github.com/tc-hib/go-winres@v0.3.3 make --product-version=git-tag --file-version=git-tag --arch=amd64,arm64
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
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"
|
||||||
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof"
|
"net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// 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"
|
|
||||||
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
|
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||||
@@ -28,8 +31,12 @@ import (
|
|||||||
"github.com/prometheus/common/version"
|
"github.com/prometheus/common/version"
|
||||||
"github.com/prometheus/exporter-toolkit/web"
|
"github.com/prometheus/exporter-toolkit/web"
|
||||||
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
|
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
||||||
|
const PROCESS_ALL_ACCESS = windows.STANDARD_RIGHTS_REQUIRED | windows.SYNCHRONIZE | windows.SPECIFIC_RIGHTS_ALL
|
||||||
|
|
||||||
// Same struct prometheus uses for their /version endpoint.
|
// Same struct prometheus uses for their /version endpoint.
|
||||||
// Separate copy to avoid pulling all of prometheus as a dependency
|
// Separate copy to avoid pulling all of prometheus as a dependency
|
||||||
type prometheusVersion struct {
|
type prometheusVersion struct {
|
||||||
@@ -41,6 +48,32 @@ type prometheusVersion struct {
|
|||||||
GoVersion string `json:"goVersion"`
|
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 {
|
||||||
|
handle, err := windows.OpenProcess(PROCESS_ALL_ACCESS, false, uint32(pid))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//nolint:errcheck
|
||||||
|
defer windows.CloseHandle(handle) // Technically this can fail, but we ignore it
|
||||||
|
|
||||||
|
err = windows.SetPriorityClass(handle, priority)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := kingpin.New("windows_exporter", "A metrics collector for Windows.")
|
app := kingpin.New("windows_exporter", "A metrics collector for Windows.")
|
||||||
var (
|
var (
|
||||||
@@ -77,6 +110,14 @@ func main() {
|
|||||||
"scrape.timeout-margin",
|
"scrape.timeout-margin",
|
||||||
"Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads.",
|
"Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads.",
|
||||||
).Default("0.5").Float64()
|
).Default("0.5").Float64()
|
||||||
|
debugEnabled = app.Flag(
|
||||||
|
"debug.enabled",
|
||||||
|
"If true, windows_exporter will expose debug endpoints under /debug/pprof.",
|
||||||
|
).Default("false").Bool()
|
||||||
|
processPriority = app.Flag(
|
||||||
|
"process.priority",
|
||||||
|
"Priority of the exporter process. Higher priorities may improve exporter responsiveness during periods of system load. Can be one of [\"realtime\", \"high\", \"abovenormal\", \"normal\", \"belownormal\", \"low\"]",
|
||||||
|
).Default("normal").String()
|
||||||
)
|
)
|
||||||
|
|
||||||
winlogConfig := &winlog.Config{}
|
winlogConfig := &winlog.Config{}
|
||||||
@@ -138,6 +179,16 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 = wmi.InitWbem(logger); err != nil {
|
if err = wmi.InitWbem(logger); err != nil {
|
||||||
_ = level.Error(logger).Log("err", err)
|
_ = level.Error(logger).Log("err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -171,15 +222,16 @@ func main() {
|
|||||||
|
|
||||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Enabled collectors: %v", strings.Join(enabledCollectorList, ", ")))
|
_ = level.Info(logger).Log("msg", fmt.Sprintf("Enabled collectors: %v", strings.Join(enabledCollectorList, ", ")))
|
||||||
|
|
||||||
http.HandleFunc(*metricsPath, withConcurrencyLimit(*maxRequests, collectors.BuildServeHTTP(*disableExporterMetrics, *timeoutMargin)))
|
mux := http.NewServeMux()
|
||||||
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
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")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
_, err := fmt.Fprintln(w, `{"status":"ok"}`)
|
_, err := fmt.Fprintln(w, `{"status":"ok"}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = level.Debug(logger).Log("Failed to write to stream", "err", err)
|
_ = level.Debug(logger).Log("msg", "Failed to write to stream", "err", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
http.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
|
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
|
// we can't use "version" directly as it is a package, and not an object that
|
||||||
// can be serialized.
|
// can be serialized.
|
||||||
err := json.NewEncoder(w).Encode(prometheusVersion{
|
err := json.NewEncoder(w).Encode(prometheusVersion{
|
||||||
@@ -194,32 +246,13 @@ func main() {
|
|||||||
http.Error(w, fmt.Sprintf("error encoding JSON: %s", err), http.StatusInternalServerError)
|
http.Error(w, fmt.Sprintf("error encoding JSON: %s", err), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if *metricsPath != "/" && *metricsPath != "" {
|
|
||||||
landingConfig := web.LandingConfig{
|
if *debugEnabled {
|
||||||
Name: "Windows Exporter",
|
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||||
Description: "Prometheus Exporter for Windows servers",
|
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||||
Version: version.Info(),
|
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||||
Links: []web.LandingLinks{
|
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||||
{
|
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||||
Address: *metricsPath,
|
|
||||||
Text: "Metrics",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Address: "/health",
|
|
||||||
Text: "Health Check",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Address: "/version",
|
|
||||||
Text: "Version Info",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
landingPage, err := web.NewLandingPage(landingConfig)
|
|
||||||
if err != nil {
|
|
||||||
_ = level.Error(logger).Log("msg", "failed to generate landing page", "err", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
http.Handle("/", landingPage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = level.Info(logger).Log("msg", "Starting windows_exporter", "version", version.Info())
|
_ = level.Info(logger).Log("msg", "Starting windows_exporter", "version", version.Info())
|
||||||
@@ -227,7 +260,7 @@ func main() {
|
|||||||
_ = level.Debug(logger).Log("msg", "Go MAXPROCS", "procs", runtime.GOMAXPROCS(0))
|
_ = level.Debug(logger).Log("msg", "Go MAXPROCS", "procs", runtime.GOMAXPROCS(0))
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
server := &http.Server{}
|
server := &http.Server{Handler: mux}
|
||||||
if err := web.ListenAndServe(server, webConfig, logger); err != nil {
|
if err := web.ListenAndServe(server, webConfig, logger); err != nil {
|
||||||
_ = level.Error(logger).Log("msg", "cannot start windows_exporter", "err", err)
|
_ = level.Error(logger).Log("msg", "cannot start windows_exporter", "err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
48
go.mod
48
go.mod
@@ -1,56 +1,52 @@
|
|||||||
module github.com/prometheus-community/windows_exporter
|
module github.com/prometheus-community/windows_exporter
|
||||||
|
|
||||||
go 1.21
|
go 1.22
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/hcsshim v0.11.4
|
github.com/Microsoft/hcsshim v0.12.5
|
||||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||||
github.com/dimchansky/utfbom v1.1.1
|
github.com/dimchansky/utfbom v1.1.1
|
||||||
github.com/go-kit/log v0.2.1
|
github.com/go-kit/log v0.2.1
|
||||||
github.com/go-ole/go-ole v1.3.0
|
github.com/go-ole/go-ole v1.3.0
|
||||||
github.com/prometheus/client_golang v1.18.0
|
github.com/prometheus/client_golang v1.19.1
|
||||||
github.com/prometheus/client_model v0.5.0
|
github.com/prometheus/client_model v0.6.1
|
||||||
github.com/prometheus/common v0.45.0
|
github.com/prometheus/common v0.55.0
|
||||||
github.com/prometheus/exporter-toolkit v0.11.0
|
github.com/prometheus/exporter-toolkit v0.11.0
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/yusufpapurcu/wmi v1.2.3
|
github.com/yusufpapurcu/wmi v1.2.4
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||||
golang.org/x/sys v0.16.0
|
golang.org/x/sys v0.22.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
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-20211218093645-b94a6e3cc137 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/containerd/cgroups v1.1.0 // indirect
|
github.com/containerd/cgroups/v3 v3.0.2 // indirect
|
||||||
github.com/containerd/containerd v1.7.0 // indirect
|
github.com/containerd/errdefs v0.1.0 // indirect
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.5.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/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
github.com/jpillora/backoff v1.0.0 // indirect
|
github.com/jpillora/backoff v1.0.0 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/procfs v0.12.0 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||||
golang.org/x/crypto v0.17.0 // indirect
|
golang.org/x/crypto v0.24.0 // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/net v0.26.0 // indirect
|
||||||
golang.org/x/net v0.18.0 // indirect
|
golang.org/x/oauth2 v0.21.0 // indirect
|
||||||
golang.org/x/oauth2 v0.12.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/sync v0.5.0 // indirect
|
golang.org/x/text v0.16.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||||
golang.org/x/tools v0.15.0 // indirect
|
google.golang.org/grpc v1.62.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
|
||||||
google.golang.org/grpc v1.56.3 // indirect
|
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
121
go.sum
121
go.sum
@@ -1,9 +1,9 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
|
github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0=
|
||||||
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
|
github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8=
|
||||||
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
|
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/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 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
||||||
@@ -15,10 +15,10 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
|
|||||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
|
||||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
|
||||||
github.com/containerd/containerd v1.7.0 h1:G/ZQr3gMZs6ZT0qPUZ15znx5QSdQdASW11nXTLTM2Pg=
|
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
|
||||||
github.com/containerd/containerd v1.7.0/go.mod h1:QfR7Efgb/6X2BDpTPJRvPTYDE9rsF0FsXX9J8sIs/sc=
|
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
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/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=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -38,15 +38,12 @@ github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU
|
|||||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
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/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/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/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-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
@@ -55,46 +52,42 @@ 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.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
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.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
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.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
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/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/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
|
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=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
|
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||||
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
|
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
|
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||||
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
|
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 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g=
|
||||||
github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q=
|
github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q=
|
||||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
@@ -107,53 +100,40 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.1/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.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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
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 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
|
||||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
|
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/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-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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
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/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
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-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-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-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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
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.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
|
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||||
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
|
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||||
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
golang.org/x/oauth2 v0.21.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-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-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.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
|
||||||
golang.org/x/sync v0.5.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-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-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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -161,43 +141,32 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.22.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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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-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-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-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/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
|
|
||||||
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
|
|
||||||
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-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.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
|
||||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
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.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
|
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||||
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
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=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@@ -207,10 +176,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.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.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.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ Param (
|
|||||||
)
|
)
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
# The MSI version is not semver compliant, so just take the numerical parts
|
||||||
|
$MsiVersion = $Version -replace '^v?([0-9\.]+).*$','$1'
|
||||||
|
|
||||||
# Get absolute path to executable before switching directories
|
# Get absolute path to executable before switching directories
|
||||||
$PathToExecutable = Resolve-Path $PathToExecutable
|
$PathToExecutable = Resolve-Path $PathToExecutable
|
||||||
# Set working dir to this directory, reset previous on exit
|
# Set working dir to this directory, reset previous on exit
|
||||||
@@ -24,8 +27,8 @@ Copy-Item -Force $PathToExecutable Work/windows_exporter.exe
|
|||||||
|
|
||||||
Write-Verbose "Creating windows_exporter-${Version}-${Arch}.msi"
|
Write-Verbose "Creating windows_exporter-${Version}-${Arch}.msi"
|
||||||
$wixArch = @{"amd64" = "x64"; "arm64" = "arm64"}[$Arch]
|
$wixArch = @{"amd64" = "x64"; "arm64" = "arm64"}[$Arch]
|
||||||
$wixOpts = "-ext WixFirewallExtension -ext WixUtilExtension"
|
|
||||||
Invoke-Expression "wix build -arch $wixArch -o .\windows_exporter-$($Version)-$($Arch).msi .\windows_exporter.wxs -d Version=$($Version) -ext WixToolset.Firewall.wixext -ext WixToolset.Util.wixext"
|
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"
|
||||||
|
|
||||||
Write-Verbose "Done!"
|
Write-Verbose "Done!"
|
||||||
Pop-Location
|
Pop-Location
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
<?define PlatformProgramFiles = "ProgramFilesFolder" ?>
|
<?define PlatformProgramFiles = "ProgramFilesFolder" ?>
|
||||||
<?endif?>
|
<?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" />
|
<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" />
|
<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." />
|
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." />
|
||||||
|
|
||||||
@@ -15,8 +17,12 @@
|
|||||||
<Property Id="EXTRA_FLAGS" Secure="yes" />
|
<Property Id="EXTRA_FLAGS" Secure="yes" />
|
||||||
<SetProperty Id="ExtraFlags" After="InstallFiles" Sequence="execute" Value="[EXTRA_FLAGS]" Condition="EXTRA_FLAGS" />
|
<SetProperty Id="ExtraFlags" After="InstallFiles" Sequence="execute" Value="[EXTRA_FLAGS]" Condition="EXTRA_FLAGS" />
|
||||||
|
|
||||||
<Property Id="LISTEN_ADDR" Secure="yes" Value="0.0.0.0" />
|
<Property Id="ADD_FIREWALL_EXCEPTION" Secure="yes" />
|
||||||
|
|
||||||
|
<Property Id="ENABLE_V1_PERFORMANCE_COUNTERS" Secure="yes" Value="yes"/>
|
||||||
|
|
||||||
<Property Id="LISTEN_PORT" Secure="yes" Value="9182" />
|
<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" />
|
<Property Id="METRICS_PATH" Secure="yes" />
|
||||||
<SetProperty Id="MetricsPathFlag" After="InstallFiles" Sequence="execute" Value="--telemetry.path [METRICS_PATH]" Condition="METRICS_PATH" />
|
<SetProperty Id="MetricsPathFlag" After="InstallFiles" Sequence="execute" Value="--telemetry.path [METRICS_PATH]" Condition="METRICS_PATH" />
|
||||||
@@ -44,17 +50,32 @@
|
|||||||
<Custom Action="RemoveEventSource" After="InstallInitialize" />
|
<Custom Action="RemoveEventSource" After="InstallInitialize" />
|
||||||
</InstallExecuteSequence>
|
</InstallExecuteSequence>
|
||||||
|
|
||||||
<Property Id="TEXTFILE_DIR" Secure="yes" />
|
<SetProperty
|
||||||
<SetProperty Id="TextfileDirFlag" After="InstallFiles" Sequence="execute" Value="--collector.textfile.directory [TEXTFILE_DIR]" Condition="TEXTFILE_DIR" />
|
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">
|
<ComponentGroup Id="Files">
|
||||||
<Component Directory="APPLICATIONROOTDIRECTORY">
|
<Component Directory="APPLICATIONROOTDIRECTORY">
|
||||||
<File Id="windows_exporter.exe" Name="windows_exporter.exe" Source="Work\windows_exporter.exe" KeyPath="yes">
|
<File Id="windows_exporter.exe" Name="windows_exporter.exe" Source="Work\windows_exporter.exe" KeyPath="yes" />
|
||||||
<fw:FirewallException Id="MetricsEndpoint" Name="windows_exporter (HTTP [LISTEN_PORT])" Description="windows_exporter HTTP endpoint" Port="[LISTEN_PORT]" Protocol="tcp" IgnoreFailure="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]">
|
||||||
<fw:RemoteAddress Value="[REMOTE_ADDR]" />
|
|
||||||
</fw:FirewallException>
|
|
||||||
</File>
|
|
||||||
<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] --web.listen-address [LISTEN_ADDR]:[LISTEN_PORT] [MetricsPathFlag] [TextfileDirFlag] [ExtraFlags]">
|
|
||||||
<util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" RestartServiceDelayInSeconds="60" />
|
<util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" RestartServiceDelayInSeconds="60" />
|
||||||
<ServiceDependency Id="wmiApSrv" />
|
<ServiceDependency Id="wmiApSrv" />
|
||||||
</ServiceInstall>
|
</ServiceInstall>
|
||||||
@@ -64,15 +85,26 @@
|
|||||||
<CreateFolder />
|
<CreateFolder />
|
||||||
</Component>
|
</Component>
|
||||||
</ComponentGroup>
|
</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">
|
<Feature Id="DefaultFeature" Level="1">
|
||||||
<ComponentGroupRef Id="Files" />
|
<ComponentGroupRef Id="Files" />
|
||||||
</Feature>
|
</Feature>
|
||||||
|
|
||||||
<Directory Id="$(var.PlatformProgramFiles)">
|
<Feature Id="FirewallException" Level="1">
|
||||||
|
<ComponentGroupRef Id="CG_FirewallException" />
|
||||||
|
</Feature>
|
||||||
|
|
||||||
|
<StandardDirectory Id="ProgramFiles64Folder">
|
||||||
<Directory Id="APPLICATIONROOTDIRECTORY" Name="windows_exporter">
|
<Directory Id="APPLICATIONROOTDIRECTORY" Name="windows_exporter">
|
||||||
<Directory Id="textfile_inputs" Name="textfile_inputs" />
|
<Directory Id="textfile_inputs" Name="textfile_inputs" />
|
||||||
</Directory>
|
</Directory>
|
||||||
</Directory>
|
</StandardDirectory>
|
||||||
</Package>
|
</Package>
|
||||||
</Wix>
|
</Wix>
|
||||||
|
|||||||
@@ -490,8 +490,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting ad metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting ad metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -649,14 +649,14 @@ type Win32_PerfRawData_DirectoryServices_DirectoryServices struct {
|
|||||||
TransitivesuboperationsPersec uint32
|
TransitivesuboperationsPersec uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_DirectoryServices_DirectoryServices
|
var dst []Win32_PerfRawData_DirectoryServices_DirectoryServices
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1350,5 +1350,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
float64(dst[0].TombstonesVisitedPersec),
|
float64(dst[0].TombstonesVisitedPersec),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,8 +145,8 @@ func (c *collector) Build() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectADCSCounters(ctx, ch); err != nil {
|
if err := c.collectADCSCounters(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting ADCS metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting ADCS metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -169,17 +169,17 @@ type perflibADCS struct {
|
|||||||
SignedCertificateTimestampListProcessingTime float64 `perflib:"Signed Certificate Timestamp List processing time (ms)"`
|
SignedCertificateTimestampListProcessingTime float64 `perflib:"Signed Certificate Timestamp List processing time (ms)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectADCSCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectADCSCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
dst := make([]perflibADCS, 0)
|
dst := make([]perflibADCS, 0)
|
||||||
if _, ok := ctx.PerfObjects["Certification Authority"]; !ok {
|
if _, ok := ctx.PerfObjects["Certification Authority"]; !ok {
|
||||||
return nil, errors.New("perflib did not contain an entry for Certification Authority")
|
return errors.New("perflib did not contain an entry for Certification Authority")
|
||||||
}
|
}
|
||||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, c.logger)
|
err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("perflib query for Certification Authority (ADCS) returned empty result set")
|
return errors.New("perflib query for Certification Authority (ADCS) returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range dst {
|
for _, d := range dst {
|
||||||
@@ -267,5 +267,5 @@ func (c *collector) collectADCSCounters(ctx *types.ScrapeContext, ch chan<- prom
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
10
pkg/collector/cache/cache.go
vendored
10
pkg/collector/cache/cache.go
vendored
@@ -254,8 +254,8 @@ func (c *collector) Build() error {
|
|||||||
|
|
||||||
// Collect implements the Collector interface
|
// Collect implements the Collector interface
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting cache metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting cache metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -295,10 +295,10 @@ type perflibCache struct {
|
|||||||
SyncPinReadsTotal float64 `perflib:"Sync Pin Reads/sec"`
|
SyncPinReadsTotal float64 `perflib:"Sync Pin Reads/sec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []perflibCache // Single-instance class, array is required but will have single entry.
|
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 := perflib.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -475,5 +475,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
dst[0].SyncPinReadsTotal,
|
dst[0].SyncPinReadsTotal,
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
|
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/ad"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/ad"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adcs"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/adcs"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/adfs"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/adfs"
|
||||||
@@ -23,6 +24,7 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||||
@@ -45,11 +47,13 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/nps"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/nps"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/os"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/os"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/physical_disk"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/physical_disk"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/printer"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/process"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/process"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/remote_fx"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/remote_fx"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/scheduled_task"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/scheduled_task"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/service"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/service"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/smb"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smb"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smbclient"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/smtp"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smtp"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/system"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/system"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/tcp"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/tcp"
|
||||||
@@ -83,6 +87,8 @@ func NewWithFlags(app *kingpin.Application) Collectors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewWithConfig To be called by the external libraries for collector initialization without running kingpin.Parse
|
// NewWithConfig To be called by the external libraries for collector initialization without running kingpin.Parse
|
||||||
|
//
|
||||||
|
//goland:noinspection GoUnusedExportedFunction
|
||||||
func NewWithConfig(logger log.Logger, config Config) Collectors {
|
func NewWithConfig(logger log.Logger, config Config) Collectors {
|
||||||
collectors := map[string]types.Collector{}
|
collectors := map[string]types.Collector{}
|
||||||
collectors[ad.Name] = ad.New(logger, &config.Ad)
|
collectors[ad.Name] = ad.New(logger, &config.Ad)
|
||||||
@@ -101,6 +107,7 @@ func NewWithConfig(logger log.Logger, config Config) Collectors {
|
|||||||
collectors[exchange.Name] = exchange.New(logger, &config.Fsrmquota)
|
collectors[exchange.Name] = exchange.New(logger, &config.Fsrmquota)
|
||||||
collectors[hyperv.Name] = hyperv.New(logger, &config.Hyperv)
|
collectors[hyperv.Name] = hyperv.New(logger, &config.Hyperv)
|
||||||
collectors[iis.Name] = iis.New(logger, &config.Iis)
|
collectors[iis.Name] = iis.New(logger, &config.Iis)
|
||||||
|
collectors[license.Name] = license.New(logger, &config.License)
|
||||||
collectors[logical_disk.Name] = logical_disk.New(logger, &config.LogicalDisk)
|
collectors[logical_disk.Name] = logical_disk.New(logger, &config.LogicalDisk)
|
||||||
collectors[logon.Name] = logon.New(logger, &config.Logon)
|
collectors[logon.Name] = logon.New(logger, &config.Logon)
|
||||||
collectors[memory.Name] = memory.New(logger, &config.Memory)
|
collectors[memory.Name] = memory.New(logger, &config.Memory)
|
||||||
@@ -123,11 +130,13 @@ func NewWithConfig(logger log.Logger, config Config) Collectors {
|
|||||||
collectors[nps.Name] = nps.New(logger, &config.Nps)
|
collectors[nps.Name] = nps.New(logger, &config.Nps)
|
||||||
collectors[os.Name] = os.New(logger, &config.Os)
|
collectors[os.Name] = os.New(logger, &config.Os)
|
||||||
collectors[physical_disk.Name] = physical_disk.New(logger, &config.PhysicalDisk)
|
collectors[physical_disk.Name] = physical_disk.New(logger, &config.PhysicalDisk)
|
||||||
|
collectors[printer.Name] = printer.New(logger, &config.Printer)
|
||||||
collectors[process.Name] = process.New(logger, &config.Process)
|
collectors[process.Name] = process.New(logger, &config.Process)
|
||||||
collectors[remote_fx.Name] = remote_fx.New(logger, &config.RemoteFx)
|
collectors[remote_fx.Name] = remote_fx.New(logger, &config.RemoteFx)
|
||||||
collectors[scheduled_task.Name] = scheduled_task.New(logger, &config.ScheduledTask)
|
collectors[scheduled_task.Name] = scheduled_task.New(logger, &config.ScheduledTask)
|
||||||
collectors[service.Name] = service.New(logger, &config.Service)
|
collectors[service.Name] = service.New(logger, &config.Service)
|
||||||
collectors[smb.Name] = smb.New(logger, &config.Smb)
|
collectors[smb.Name] = smb.New(logger, &config.Smb)
|
||||||
|
collectors[smbclient.Name] = smbclient.New(logger, &config.SmbClient)
|
||||||
collectors[smtp.Name] = smtp.New(logger, &config.Smtp)
|
collectors[smtp.Name] = smtp.New(logger, &config.Smtp)
|
||||||
collectors[system.Name] = system.New(logger, &config.System)
|
collectors[system.Name] = system.New(logger, &config.System)
|
||||||
collectors[teradici_pcoip.Name] = teradici_pcoip.New(logger, &config.TeradiciPcoip)
|
collectors[teradici_pcoip.Name] = teradici_pcoip.New(logger, &config.TeradiciPcoip)
|
||||||
@@ -161,11 +170,12 @@ func (c *Collectors) SetPerfCounterQuery() error {
|
|||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
|
||||||
perfCounterDependencies []string
|
perfCounterNames []string
|
||||||
perfCounterNames []string
|
perfIndicies []string
|
||||||
perfIndicies []string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
perfCounterDependencies := make([]string, 0, len(c.collectors))
|
||||||
|
|
||||||
for _, collector := range c.collectors {
|
for _, collector := range c.collectors {
|
||||||
perfCounterNames, err = collector.GetPerfCounter()
|
perfCounterNames, err = collector.GetPerfCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/exchange"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||||
@@ -38,11 +39,13 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/nps"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/nps"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/os"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/os"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/physical_disk"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/physical_disk"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/printer"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/process"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/process"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/remote_fx"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/remote_fx"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/scheduled_task"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/scheduled_task"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/service"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/service"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/smb"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smb"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smbclient"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/smtp"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smtp"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/system"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/system"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/tcp"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/tcp"
|
||||||
@@ -72,6 +75,7 @@ type Config struct {
|
|||||||
Fsrmquota exchange.Config `yaml:"fsrmquota"`
|
Fsrmquota exchange.Config `yaml:"fsrmquota"`
|
||||||
Hyperv hyperv.Config `yaml:"hyperv"`
|
Hyperv hyperv.Config `yaml:"hyperv"`
|
||||||
Iis iis.Config `yaml:"iis"`
|
Iis iis.Config `yaml:"iis"`
|
||||||
|
License license.Config `yaml:"license"`
|
||||||
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
||||||
Logon logon.Config `yaml:"logon"`
|
Logon logon.Config `yaml:"logon"`
|
||||||
Memory memory.Config `yaml:"memory"`
|
Memory memory.Config `yaml:"memory"`
|
||||||
@@ -94,11 +98,13 @@ type Config struct {
|
|||||||
Nps nps.Config `yaml:"nps"`
|
Nps nps.Config `yaml:"nps"`
|
||||||
Os os.Config `yaml:"os"`
|
Os os.Config `yaml:"os"`
|
||||||
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
|
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
|
||||||
|
Printer printer.Config `yaml:"printer"`
|
||||||
Process process.Config `yaml:"process"`
|
Process process.Config `yaml:"process"`
|
||||||
RemoteFx remote_fx.Config `yaml:"remote_fx"`
|
RemoteFx remote_fx.Config `yaml:"remote_fx"`
|
||||||
ScheduledTask scheduled_task.Config `yaml:"scheduled_task"`
|
ScheduledTask scheduled_task.Config `yaml:"scheduled_task"`
|
||||||
Service service.Config `yaml:"service"`
|
Service service.Config `yaml:"service"`
|
||||||
Smb smb.Config `yaml:"smb"`
|
Smb smb.Config `yaml:"smb"`
|
||||||
|
SmbClient smbclient.Config `yaml:"smbclient"`
|
||||||
Smtp smtp.Config `yaml:"smtp"`
|
Smtp smtp.Config `yaml:"smtp"`
|
||||||
System system.Config `yaml:"system"`
|
System system.Config `yaml:"system"`
|
||||||
TeradiciPcoip teradici_pcoip.Config `yaml:"teradici_pcoip"`
|
TeradiciPcoip teradici_pcoip.Config `yaml:"teradici_pcoip"`
|
||||||
@@ -112,6 +118,8 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConfigDefaults Is an interface to be used by the external libraries. It holds all ConfigDefaults form all collectors
|
// ConfigDefaults Is an interface to be used by the external libraries. It holds all ConfigDefaults form all collectors
|
||||||
|
//
|
||||||
|
//goland:noinspection GoUnusedGlobalVariable
|
||||||
var ConfigDefaults = Config{
|
var ConfigDefaults = Config{
|
||||||
Ad: ad.ConfigDefaults,
|
Ad: ad.ConfigDefaults,
|
||||||
Adcs: adcs.ConfigDefaults,
|
Adcs: adcs.ConfigDefaults,
|
||||||
@@ -129,6 +137,7 @@ var ConfigDefaults = Config{
|
|||||||
Fsrmquota: exchange.ConfigDefaults,
|
Fsrmquota: exchange.ConfigDefaults,
|
||||||
Hyperv: hyperv.ConfigDefaults,
|
Hyperv: hyperv.ConfigDefaults,
|
||||||
Iis: iis.ConfigDefaults,
|
Iis: iis.ConfigDefaults,
|
||||||
|
License: license.ConfigDefaults,
|
||||||
LogicalDisk: logical_disk.ConfigDefaults,
|
LogicalDisk: logical_disk.ConfigDefaults,
|
||||||
Logon: logon.ConfigDefaults,
|
Logon: logon.ConfigDefaults,
|
||||||
Memory: memory.ConfigDefaults,
|
Memory: memory.ConfigDefaults,
|
||||||
@@ -151,11 +160,13 @@ var ConfigDefaults = Config{
|
|||||||
Nps: nps.ConfigDefaults,
|
Nps: nps.ConfigDefaults,
|
||||||
Os: os.ConfigDefaults,
|
Os: os.ConfigDefaults,
|
||||||
PhysicalDisk: physical_disk.ConfigDefaults,
|
PhysicalDisk: physical_disk.ConfigDefaults,
|
||||||
|
Printer: printer.ConfigDefaults,
|
||||||
Process: process.ConfigDefaults,
|
Process: process.ConfigDefaults,
|
||||||
RemoteFx: remote_fx.ConfigDefaults,
|
RemoteFx: remote_fx.ConfigDefaults,
|
||||||
ScheduledTask: scheduled_task.ConfigDefaults,
|
ScheduledTask: scheduled_task.ConfigDefaults,
|
||||||
Service: service.ConfigDefaults,
|
Service: service.ConfigDefaults,
|
||||||
Smb: smb.ConfigDefaults,
|
Smb: smb.ConfigDefaults,
|
||||||
|
SmbClient: smbclient.ConfigDefaults,
|
||||||
Smtp: smtp.ConfigDefaults,
|
Smtp: smtp.ConfigDefaults,
|
||||||
System: system.ConfigDefaults,
|
System: system.ConfigDefaults,
|
||||||
TeradiciPcoip: teradici_pcoip.ConfigDefaults,
|
TeradiciPcoip: teradici_pcoip.ConfigDefaults,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Microsoft/hcsshim"
|
"github.com/Microsoft/hcsshim"
|
||||||
@@ -193,8 +192,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting collector metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting collector metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -208,12 +207,12 @@ func (c *collector) containerClose(container hcsshim.Container) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
// Types Container is passed to get the containers compute systems only
|
// Types Container is passed to get the containers compute systems only
|
||||||
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
|
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "Err in Getting containers", "err", err)
|
_ = level.Error(c.logger).Log("msg", "Err in Getting containers", "err", err)
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
count := len(containers)
|
count := len(containers)
|
||||||
@@ -224,7 +223,7 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
float64(count),
|
float64(count),
|
||||||
)
|
)
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
containerPrefixes := make(map[string]string)
|
containerPrefixes := make(map[string]string)
|
||||||
@@ -322,18 +321,18 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for containers")
|
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for containers")
|
||||||
return nil, nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(hnsEndpoints) == 0 {
|
if len(hnsEndpoints) == 0 {
|
||||||
_ = level.Info(c.logger).Log("msg", fmt.Sprintf("No network stats for containers to collect"))
|
_ = level.Info(c.logger).Log("msg", "No network stats for containers to collect")
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, endpoint := range hnsEndpoints {
|
for _, endpoint := range hnsEndpoints {
|
||||||
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
|
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for interface %s", endpoint.Id), "err", err)
|
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for interface "+endpoint.Id, "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +341,7 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
endpointId := strings.ToUpper(endpoint.Id)
|
endpointId := strings.ToUpper(endpoint.Id)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Failed to collect network stats for container %s", containerId))
|
_ = level.Warn(c.logger).Log("msg", "Failed to collect network stats for container "+containerId)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +385,7 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainerIdWithPrefix(containerDetails hcsshim.ContainerProperties) string {
|
func getContainerIdWithPrefix(containerDetails hcsshim.ContainerProperties) string {
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ func (c *collector) Build() error {
|
|||||||
)
|
)
|
||||||
c.ProcessorPrivUtility = prometheus.NewDesc(
|
c.ProcessorPrivUtility = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "processor_privileged_utility_total"),
|
prometheus.BuildFQName(types.Namespace, Name, "processor_privileged_utility_total"),
|
||||||
"Processor Privilieged Utility represents is the amount of time the core has spent executing instructions inside the kernel",
|
"Processor Privileged Utility represents is the amount of time the core has spent executing instructions inside the kernel",
|
||||||
[]string{"core"},
|
[]string{"core"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
@@ -198,9 +198,9 @@ type perflibProcessor struct {
|
|||||||
DPCRate float64 `perflib:"DPC Rate"`
|
DPCRate float64 `perflib:"DPC Rate"`
|
||||||
DPCsQueued float64 `perflib:"DPCs Queued/sec"`
|
DPCsQueued float64 `perflib:"DPCs Queued/sec"`
|
||||||
Interrupts float64 `perflib:"Interrupts/sec"`
|
Interrupts float64 `perflib:"Interrupts/sec"`
|
||||||
PercentC2Time float64 `perflib:"% C1 Time"`
|
PercentC1Time float64 `perflib:"% C1 Time"`
|
||||||
PercentC3Time float64 `perflib:"% C2 Time"`
|
PercentC2Time float64 `perflib:"% C2 Time"`
|
||||||
PercentC1Time float64 `perflib:"% C3 Time"`
|
PercentC3Time float64 `perflib:"% C3 Time"`
|
||||||
PercentDPCTime float64 `perflib:"% DPC Time"`
|
PercentDPCTime float64 `perflib:"% DPC Time"`
|
||||||
PercentIdleTime float64 `perflib:"% Idle Time"`
|
PercentIdleTime float64 `perflib:"% Idle Time"`
|
||||||
PercentInterruptTime float64 `perflib:"% Interrupt Time"`
|
PercentInterruptTime float64 `perflib:"% Interrupt Time"`
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func (c *collector) GetPerfCounter() ([]string, error) {
|
|||||||
func (c *collector) Build() error {
|
func (c *collector) Build() error {
|
||||||
c.CpuInfo = prometheus.NewDesc(
|
c.CpuInfo = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, "", Name),
|
prometheus.BuildFQName(types.Namespace, "", Name),
|
||||||
"Labeled CPU information as provided provided by Win32_Processor",
|
"Labelled CPU information as provided provided by Win32_Processor",
|
||||||
[]string{
|
[]string{
|
||||||
"architecture",
|
"architecture",
|
||||||
"device_id",
|
"device_id",
|
||||||
@@ -86,23 +86,23 @@ type win32_Processor struct {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting cpu_info metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting cpu_info metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_Processor
|
var dst []win32_Processor
|
||||||
// We use a static query here because the provided methods in wmi.go all issue a SELECT *;
|
// We use a static query here because the provided methods in wmi.go all issue a SELECT *;
|
||||||
// This results in the time-consuming LoadPercentage field being read which seems to measure each CPU
|
// This results in the time-consuming LoadPercentage field being read which seems to measure each CPU
|
||||||
// serially over a 1 second interval, so the scrape time is at least 1s * num_sockets
|
// serially over a 1 second interval, so the scrape time is at least 1s * num_sockets
|
||||||
if err := wmi.Query(win32ProcessorQuery, &dst); err != nil {
|
if err := wmi.Query(win32ProcessorQuery, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some CPUs end up exposing trailing spaces for certain strings, so clean them up
|
// Some CPUs end up exposing trailing spaces for certain strings, so clean them up
|
||||||
@@ -121,5 +121,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func (c *collector) Build() error {
|
|||||||
)
|
)
|
||||||
c.Hostname = prometheus.NewDesc(
|
c.Hostname = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "hostname"),
|
prometheus.BuildFQName(types.Namespace, Name, "hostname"),
|
||||||
"Labeled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain",
|
"Labelled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain",
|
||||||
[]string{
|
[]string{
|
||||||
"hostname",
|
"hostname",
|
||||||
"domain",
|
"domain",
|
||||||
@@ -77,21 +77,21 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting cs metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting cs metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
// Get systeminfo for number of processors
|
// Get systeminfo for number of processors
|
||||||
systemInfo := sysinfoapi.GetSystemInfo()
|
systemInfo := sysinfoapi.GetSystemInfo()
|
||||||
|
|
||||||
// Get memory status for physical memory
|
// Get memory status for physical memory
|
||||||
mem, err := sysinfoapi.GlobalMemoryStatusEx()
|
mem, err := sysinfoapi.GlobalMemoryStatusEx()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -108,15 +108,15 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
|
|
||||||
hostname, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSHostname)
|
hostname, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSHostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
domain, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSDomain)
|
domain, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSDomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
fqdn, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSFullyQualified)
|
fqdn, err := sysinfoapi.GetComputerName(sysinfoapi.ComputerNameDNSFullyQualified)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -128,5 +128,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
fqdn,
|
fqdn,
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var ConfigDefaults = Config{
|
var ConfigDefaults = Config{
|
||||||
DfsrEnabledCollectors: "",
|
DfsrEnabledCollectors: "connection,folder,volume",
|
||||||
}
|
}
|
||||||
|
|
||||||
// collector contains the metric and state data of the DFSR collectors.
|
// collector contains the metric and state data of the DFSR collectors.
|
||||||
@@ -130,8 +130,9 @@ func (c *collector) SetLogger(logger log.Logger) {
|
|||||||
|
|
||||||
func (c *collector) GetPerfCounter() ([]string, error) {
|
func (c *collector) GetPerfCounter() ([]string, error) {
|
||||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||||
var perflibDependencies []string
|
expandedChildCollectors := utils.ExpandEnabledChildCollectors(*c.dfsrEnabledCollectors)
|
||||||
for _, source := range utils.ExpandEnabledChildCollectors(*c.dfsrEnabledCollectors) {
|
perflibDependencies := make([]string, 0, len(expandedChildCollectors))
|
||||||
|
for _, source := range expandedChildCollectors {
|
||||||
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
|
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,21 +150,21 @@ var (
|
|||||||
|
|
||||||
// Collect sends the metric values for each metric to the provided prometheus Metric channel.
|
// 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, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting disk_drive_info metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting disk_drive_info metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_DiskDrive
|
var dst []Win32_DiskDrive
|
||||||
|
|
||||||
if err := wmi.Query(win32DiskQuery, &dst); err != nil {
|
if err := wmi.Query(win32DiskQuery, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, disk := range dst {
|
for _, disk := range dst {
|
||||||
@@ -222,5 +222,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,8 +208,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting dns metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting dns metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -261,14 +261,14 @@ type Win32_PerfRawData_DNS_DNS struct {
|
|||||||
ZoneTransferSOARequestSent uint32
|
ZoneTransferSOARequestSent uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_DNS_DNS
|
var dst []Win32_PerfRawData_DNS_DNS
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -520,5 +520,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
float64(dst[0].SecureUpdateReceived),
|
float64(dst[0].SecureUpdateReceived),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting fsrmquota metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting fsrmquota metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -142,14 +142,14 @@ type MSFT_FSRMQuota struct {
|
|||||||
SoftLimit bool
|
SoftLimit bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []MSFT_FSRMQuota
|
var dst []MSFT_FSRMQuota
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
|
|
||||||
var count int
|
var count int
|
||||||
|
|
||||||
if err := wmi.QueryNamespace(q, &dst, "root/microsoft/windows/fsrm"); err != nil {
|
if err := wmi.QueryNamespace(q, &dst, "root/microsoft/windows/fsrm"); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, quota := range dst {
|
for _, quota := range dst {
|
||||||
@@ -214,5 +214,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(count),
|
float64(count),
|
||||||
)
|
)
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/collectors/version"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"github.com/prometheus/common/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Collectors) BuildServeHTTP(disableExporterMetrics bool, timeoutMargin float64) http.HandlerFunc {
|
func (c *Collectors) BuildServeHTTP(disableExporterMetrics bool, timeoutMargin float64) http.HandlerFunc {
|
||||||
@@ -32,7 +32,14 @@ func (c *Collectors) BuildServeHTTP(disableExporterMetrics bool, timeoutMargin f
|
|||||||
}
|
}
|
||||||
filteredCollectors[name] = col
|
filteredCollectors[name] = col
|
||||||
}
|
}
|
||||||
return nil, NewPrometheus(timeout, c, c.logger)
|
|
||||||
|
filtered := Collectors{
|
||||||
|
logger: c.logger,
|
||||||
|
collectors: filteredCollectors,
|
||||||
|
perfCounterQuery: c.perfCounterQuery,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, NewPrometheus(timeout, &filtered, c.logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
@@ -743,63 +743,63 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectVmHealth(ch); err != nil {
|
if err := c.collectVmHealth(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV health status metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV health status metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmVid(ch); err != nil {
|
if err := c.collectVmVid(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV pages metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV pages metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmHv(ch); err != nil {
|
if err := c.collectVmHv(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV hv status metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV hv status metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmProcessor(ch); err != nil {
|
if err := c.collectVmProcessor(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV processor metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV processor metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectHostLPUsage(ch); err != nil {
|
if err := c.collectHostLPUsage(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV host logical processors metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV host logical processors metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectHostCpuUsage(ch); err != nil {
|
if err := c.collectHostCpuUsage(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV host CPU metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV host CPU metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmCpuUsage(ch); err != nil {
|
if err := c.collectVmCpuUsage(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV VM CPU metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV VM CPU metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmSwitch(ch); err != nil {
|
if err := c.collectVmSwitch(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV switch metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV switch metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmEthernet(ch); err != nil {
|
if err := c.collectVmEthernet(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV ethernet metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV ethernet metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmStorage(ch); err != nil {
|
if err := c.collectVmStorage(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual storage metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual storage metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmNetwork(ch); err != nil {
|
if err := c.collectVmNetwork(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual network metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual network metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectVmMemory(ch); err != nil {
|
if err := c.collectVmMemory(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual memory metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting hyperV virtual memory metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,11 +812,11 @@ type Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
|
|||||||
HealthOk uint32
|
HealthOk uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmHealth(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmHealth(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
|
var dst []Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, health := range dst {
|
for _, health := range dst {
|
||||||
@@ -834,7 +834,7 @@ func (c *collector) collectVmHealth(ch chan<- prometheus.Metric) (*prometheus.De
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition ..,
|
// Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition ..,
|
||||||
@@ -845,11 +845,11 @@ type Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition struct {
|
|||||||
RemotePhysicalPages uint64
|
RemotePhysicalPages uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmVid(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmVid(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition
|
var dst []Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, page := range dst {
|
for _, page := range dst {
|
||||||
@@ -880,7 +880,7 @@ func (c *collector) collectVmVid(ch chan<- prometheus.Metric) (*prometheus.Desc,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition ...
|
// Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition ...
|
||||||
@@ -909,11 +909,11 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition struct {
|
|||||||
VirtualTLBPages uint64
|
VirtualTLBPages uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmHv(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmHv(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition
|
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1038,7 +1038,7 @@ func (c *collector) collectVmHv(ch chan<- prometheus.Metric) (*prometheus.Desc,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_HvStats_HyperVHypervisor ...
|
// Win32_PerfRawData_HvStats_HyperVHypervisor ...
|
||||||
@@ -1047,11 +1047,11 @@ type Win32_PerfRawData_HvStats_HyperVHypervisor struct {
|
|||||||
VirtualProcessors uint64
|
VirtualProcessors uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmProcessor(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmProcessor(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisor
|
var dst []Win32_PerfRawData_HvStats_HyperVHypervisor
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1070,7 +1070,7 @@ func (c *collector) collectVmProcessor(ch chan<- prometheus.Metric) (*prometheus
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor ...
|
// Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor ...
|
||||||
@@ -1081,11 +1081,11 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor struct {
|
|||||||
PercentTotalRunTime uint
|
PercentTotalRunTime uint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectHostLPUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectHostLPUsage(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
|
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1123,7 +1123,7 @@ func (c *collector) collectHostLPUsage(ch chan<- prometheus.Metric) (*prometheus
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor ...
|
// Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor ...
|
||||||
@@ -1136,11 +1136,11 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor struct {
|
|||||||
CPUWaitTimePerDispatch uint64
|
CPUWaitTimePerDispatch uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectHostCpuUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectHostCpuUsage(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
|
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1191,7 +1191,7 @@ func (c *collector) collectHostCpuUsage(ch chan<- prometheus.Metric) (*prometheu
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor ...
|
// Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor ...
|
||||||
@@ -1204,11 +1204,11 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor struct {
|
|||||||
CPUWaitTimePerDispatch uint64
|
CPUWaitTimePerDispatch uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmCpuUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmCpuUsage(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
|
var dst []Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1266,7 +1266,7 @@ func (c *collector) collectVmCpuUsage(ch chan<- prometheus.Metric) (*prometheus.
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch ...
|
// Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch ...
|
||||||
@@ -1298,11 +1298,11 @@ type Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch struct {
|
|||||||
PurgedMacAddressesPersec uint64
|
PurgedMacAddressesPersec uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmSwitch(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmSwitch(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch
|
var dst []Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1449,7 +1449,7 @@ func (c *collector) collectVmSwitch(ch chan<- prometheus.Metric) (*prometheus.De
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter ...
|
// Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter ...
|
||||||
@@ -1463,11 +1463,11 @@ type Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter struct {
|
|||||||
FramesSentPersec uint64
|
FramesSentPersec uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmEthernet(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmEthernet(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter
|
var dst []Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1519,7 +1519,7 @@ func (c *collector) collectVmEthernet(ch chan<- prometheus.Metric) (*prometheus.
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_Counters_HyperVVirtualStorageDevice ...
|
// Win32_PerfRawData_Counters_HyperVVirtualStorageDevice ...
|
||||||
@@ -1533,11 +1533,11 @@ type Win32_PerfRawData_Counters_HyperVVirtualStorageDevice struct {
|
|||||||
WriteOperationsPerSec uint64
|
WriteOperationsPerSec uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmStorage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmStorage(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_Counters_HyperVVirtualStorageDevice
|
var dst []Win32_PerfRawData_Counters_HyperVVirtualStorageDevice
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1588,7 +1588,7 @@ func (c *collector) collectVmStorage(ch chan<- prometheus.Metric) (*prometheus.D
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter ...
|
// Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter ...
|
||||||
@@ -1602,11 +1602,11 @@ type Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter struct {
|
|||||||
PacketsSentPersec uint64
|
PacketsSentPersec uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmNetwork(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmNetwork(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter
|
var dst []Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1657,7 +1657,7 @@ func (c *collector) collectVmNetwork(ch chan<- prometheus.Metric) (*prometheus.D
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM ...
|
// Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM ...
|
||||||
@@ -1675,11 +1675,11 @@ type Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM struct {
|
|||||||
RemovedMemory uint64
|
RemovedMemory uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectVmMemory(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectVmMemory(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
|
var dst []Win32_PerfRawData_BalancerStats_HyperVDynamicMemoryVM
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, obj := range dst {
|
for _, obj := range dst {
|
||||||
@@ -1758,5 +1758,5 @@ func (c *collector) collectVmMemory(ch chan<- prometheus.Metric) (*prometheus.De
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func getIISVersion(logger log.Logger) simple_version {
|
|||||||
defer func() {
|
defer func() {
|
||||||
err = k.Close()
|
err = k.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = level.Warn(logger).Log("msg", fmt.Sprintf("Failed to close registry key"), "err", err)
|
_ = level.Warn(logger).Log("msg", "Failed to close registry key", "err", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -85,6 +85,8 @@ type collector struct {
|
|||||||
appInclude *string
|
appInclude *string
|
||||||
appExclude *string
|
appExclude *string
|
||||||
|
|
||||||
|
Info *prometheus.Desc
|
||||||
|
|
||||||
// Web Service
|
// Web Service
|
||||||
CurrentAnonymousUsers *prometheus.Desc
|
CurrentAnonymousUsers *prometheus.Desc
|
||||||
CurrentBlockedAsyncIORequests *prometheus.Desc
|
CurrentBlockedAsyncIORequests *prometheus.Desc
|
||||||
@@ -300,6 +302,15 @@ func (c *collector) Build() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Info = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||||
|
"ISS information",
|
||||||
|
[]string{},
|
||||||
|
prometheus.Labels{
|
||||||
|
"version": fmt.Sprintf("%d.%d", c.iis_version.major, c.iis_version.minor),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
// Web Service
|
// Web Service
|
||||||
c.CurrentAnonymousUsers = prometheus.NewDesc(
|
c.CurrentAnonymousUsers = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "current_anonymous_users"),
|
prometheus.BuildFQName(types.Namespace, Name, "current_anonymous_users"),
|
||||||
@@ -915,23 +926,23 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectWebService(ctx, ch); err != nil {
|
if err := c.collectWebService(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectAPP_POOL_WAS(ctx, ch); err != nil {
|
if err := c.collectAPP_POOL_WAS(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectW3SVC_W3WP(ctx, ch); err != nil {
|
if err := c.collectW3SVC_W3WP(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc, err := c.collectWebServiceCache(ctx, ch); err != nil {
|
if err := c.collectWebServiceCache(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting iis metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,12 +1039,18 @@ func dedupIISNames[V hasGetIISName](services []V) map[string]V {
|
|||||||
return webServiceDeDuplicated
|
return webServiceDeDuplicated
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectWebService(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectWebService(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var webService []perflibWebService
|
var webService []perflibWebService
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Web Service"], &webService, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["Web Service"], &webService, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.Info,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
webServiceDeDuplicated := dedupIISNames(webService)
|
webServiceDeDuplicated := dedupIISNames(webService)
|
||||||
|
|
||||||
for name, app := range webServiceDeDuplicated {
|
for name, app := range webServiceDeDuplicated {
|
||||||
@@ -1281,7 +1298,7 @@ func (c *collector) collectWebService(ctx *types.ScrapeContext, ch chan<- promet
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type perflibAPP_POOL_WAS struct {
|
type perflibAPP_POOL_WAS struct {
|
||||||
@@ -1314,10 +1331,10 @@ var applicationStates = map[uint32]string{
|
|||||||
7: "Delete Pending",
|
7: "Delete Pending",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectAPP_POOL_WAS(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectAPP_POOL_WAS(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var APP_POOL_WAS []perflibAPP_POOL_WAS
|
var APP_POOL_WAS []perflibAPP_POOL_WAS
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["APP_POOL_WAS"], &APP_POOL_WAS, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["APP_POOL_WAS"], &APP_POOL_WAS, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
appPoolDeDuplicated := dedupIISNames(APP_POOL_WAS)
|
appPoolDeDuplicated := dedupIISNames(APP_POOL_WAS)
|
||||||
@@ -1417,7 +1434,7 @@ func (c *collector) collectAPP_POOL_WAS(ctx *types.ScrapeContext, ch chan<- prom
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var workerProcessNameExtractor = regexp.MustCompile(`^(\d+)_(.+)$`)
|
var workerProcessNameExtractor = regexp.MustCompile(`^(\d+)_(.+)$`)
|
||||||
@@ -1491,10 +1508,10 @@ type perflibW3SVC_W3WP_IIS8 struct {
|
|||||||
WebSocketConnectionsRejected float64 `perflib:"WebSocket Connections Rejected / Sec"`
|
WebSocketConnectionsRejected float64 `perflib:"WebSocket Connections Rejected / Sec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var W3SVC_W3WP []perflibW3SVC_W3WP
|
var W3SVC_W3WP []perflibW3SVC_W3WP
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
w3svcW3WPDeduplicated := dedupIISNames(W3SVC_W3WP)
|
w3svcW3WPDeduplicated := dedupIISNames(W3SVC_W3WP)
|
||||||
@@ -1753,7 +1770,7 @@ func (c *collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, ch chan<- promet
|
|||||||
if c.iis_version.major >= 8 {
|
if c.iis_version.major >= 8 {
|
||||||
var W3SVC_W3WP_IIS8 []perflibW3SVC_W3WP_IIS8
|
var W3SVC_W3WP_IIS8 []perflibW3SVC_W3WP_IIS8
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP_IIS8, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["W3SVC_W3WP"], &W3SVC_W3WP_IIS8, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
w3svcW3WPIIS8Deduplicated := dedupIISNames(W3SVC_W3WP_IIS8)
|
w3svcW3WPIIS8Deduplicated := dedupIISNames(W3SVC_W3WP_IIS8)
|
||||||
@@ -1839,7 +1856,7 @@ func (c *collector) collectW3SVC_W3WP(ctx *types.ScrapeContext, ch chan<- promet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type perflibWebServiceCache struct {
|
type perflibWebServiceCache struct {
|
||||||
@@ -1889,10 +1906,10 @@ type perflibWebServiceCache struct {
|
|||||||
ServiceCache_OutputCacheQueriesTotal float64
|
ServiceCache_OutputCacheQueriesTotal float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectWebServiceCache(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectWebServiceCache(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var WebServiceCache []perflibWebServiceCache
|
var WebServiceCache []perflibWebServiceCache
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Web Service Cache"], &WebServiceCache, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["Web Service Cache"], &WebServiceCache, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, app := range WebServiceCache {
|
for _, app := range WebServiceCache {
|
||||||
@@ -2080,5 +2097,5 @@ func (c *collector) collectWebServiceCache(ctx *types.ScrapeContext, ch chan<- p
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
95
pkg/collector/license/license.go
Normal file
95
pkg/collector/license/license.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package license
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alecthomas/kingpin/v2"
|
||||||
|
"github.com/go-kit/log"
|
||||||
|
"github.com/go-kit/log/level"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/headers/slc"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Name = "license"
|
||||||
|
|
||||||
|
var labelMap = map[slc.SL_GENUINE_STATE]string{
|
||||||
|
slc.SL_GEN_STATE_IS_GENUINE: "genuine",
|
||||||
|
slc.SL_GEN_STATE_INVALID_LICENSE: "invalid_license",
|
||||||
|
slc.SL_GEN_STATE_TAMPERED: "tampered",
|
||||||
|
slc.SL_GEN_STATE_OFFLINE: "offline",
|
||||||
|
slc.SL_GEN_STATE_LAST: "last",
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct{}
|
||||||
|
|
||||||
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
|
// A collector is a Prometheus collector for WMI Win32_PerfRawData_DNS_DNS metrics
|
||||||
|
type collector struct {
|
||||||
|
logger log.Logger
|
||||||
|
|
||||||
|
LicenseStatus *prometheus.Desc
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(logger log.Logger, _ *Config) types.Collector {
|
||||||
|
c := &collector{}
|
||||||
|
c.SetLogger(logger)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithFlags(_ *kingpin.Application) types.Collector {
|
||||||
|
return &collector{}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return []string{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) Build() error {
|
||||||
|
c.LicenseStatus = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "status"),
|
||||||
|
"Status of windows license",
|
||||||
|
[]string{"state"},
|
||||||
|
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 license metrics", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
|
status, err := slc.SLIsWindowsGenuineLocal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range labelMap {
|
||||||
|
val := 0.0
|
||||||
|
if status == k {
|
||||||
|
val = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(c.LicenseStatus, prometheus.GaugeValue, val, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
12
pkg/collector/license/license_test.go
Normal file
12
pkg/collector/license/license_test.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package license_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkCollector(b *testing.B) {
|
||||||
|
testutils.FuncBenchmarkCollector(b, license.Name, license.NewWithFlags)
|
||||||
|
}
|
||||||
@@ -3,8 +3,14 @@
|
|||||||
package logical_disk
|
package logical_disk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
@@ -38,6 +44,8 @@ type collector struct {
|
|||||||
volumeInclude *string
|
volumeInclude *string
|
||||||
volumeExclude *string
|
volumeExclude *string
|
||||||
|
|
||||||
|
Information *prometheus.Desc
|
||||||
|
ReadOnly *prometheus.Desc
|
||||||
RequestsQueued *prometheus.Desc
|
RequestsQueued *prometheus.Desc
|
||||||
AvgReadQueue *prometheus.Desc
|
AvgReadQueue *prometheus.Desc
|
||||||
AvgWriteQueue *prometheus.Desc
|
AvgWriteQueue *prometheus.Desc
|
||||||
@@ -59,6 +67,14 @@ type collector struct {
|
|||||||
volumeExcludePattern *regexp.Regexp
|
volumeExcludePattern *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type volumeInfo struct {
|
||||||
|
filesystem string
|
||||||
|
serialNumber string
|
||||||
|
label string
|
||||||
|
volumeType string
|
||||||
|
readonly float64
|
||||||
|
}
|
||||||
|
|
||||||
func New(logger log.Logger, config *Config) types.Collector {
|
func New(logger log.Logger, config *Config) types.Collector {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = &ConfigDefaults
|
config = &ConfigDefaults
|
||||||
@@ -100,6 +116,18 @@ func (c *collector) GetPerfCounter() ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) Build() error {
|
func (c *collector) Build() error {
|
||||||
|
c.Information = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||||
|
"A metric with a constant '1' value labeled with logical disk information",
|
||||||
|
[]string{"disk", "type", "volume", "volume_name", "filesystem", "serial_number"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.ReadOnly = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "readonly"),
|
||||||
|
"Whether the logical disk is read-only",
|
||||||
|
[]string{"volume"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
c.RequestsQueued = prometheus.NewDesc(
|
c.RequestsQueued = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "requests_queued"),
|
prometheus.BuildFQName(types.Namespace, Name, "requests_queued"),
|
||||||
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)",
|
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)",
|
||||||
@@ -229,8 +257,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting logical_disk metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting logical_disk metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -259,10 +287,16 @@ type logicalDisk struct {
|
|||||||
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
|
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []logicalDisk
|
var (
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["LogicalDisk"], &dst, c.logger); err != nil {
|
err error
|
||||||
return nil, err
|
diskID string
|
||||||
|
info volumeInfo
|
||||||
|
dst []logicalDisk
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = perflib.UnmarshalObject(ctx.PerfObjects["LogicalDisk"], &dst, c.logger); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, volume := range dst {
|
for _, volume := range dst {
|
||||||
@@ -272,6 +306,28 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diskID, err = getDiskIDByVolume(volume.Name)
|
||||||
|
if err != nil {
|
||||||
|
_ = level.Warn(c.logger).Log("msg", "failed to get disk ID for "+volume.Name, "err", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err = getVolumeInfo(volume.Name)
|
||||||
|
if err != nil {
|
||||||
|
_ = level.Warn(c.logger).Log("msg", "failed to get volume information for %s"+volume.Name, "err", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.Information,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
1,
|
||||||
|
diskID,
|
||||||
|
info.volumeType,
|
||||||
|
volume.Name,
|
||||||
|
info.label,
|
||||||
|
info.filesystem,
|
||||||
|
info.serialNumber,
|
||||||
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.RequestsQueued,
|
c.RequestsQueued,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
@@ -385,5 +441,108 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDriveType(driveType uint32) string {
|
||||||
|
switch driveType {
|
||||||
|
case windows.DRIVE_UNKNOWN:
|
||||||
|
return "unknown"
|
||||||
|
case windows.DRIVE_NO_ROOT_DIR:
|
||||||
|
return "norootdir"
|
||||||
|
case windows.DRIVE_REMOVABLE:
|
||||||
|
return "removable"
|
||||||
|
case windows.DRIVE_FIXED:
|
||||||
|
return "fixed"
|
||||||
|
case windows.DRIVE_REMOTE:
|
||||||
|
return "remote"
|
||||||
|
case windows.DRIVE_CDROM:
|
||||||
|
return "cdrom"
|
||||||
|
case windows.DRIVE_RAMDISK:
|
||||||
|
return "ramdisk"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// diskExtentSize Size of the DiskExtent structure in bytes.
|
||||||
|
const diskExtentSize = 24
|
||||||
|
|
||||||
|
// getDiskIDByVolume returns the disk ID for a given volume.
|
||||||
|
func getDiskIDByVolume(rootDrive string) (string, error) {
|
||||||
|
// Open a volume handle to the Disk Root.
|
||||||
|
var err error
|
||||||
|
var f windows.Handle
|
||||||
|
|
||||||
|
// mode has to include FILE_SHARE permission to allow concurrent access to the disk.
|
||||||
|
// use 0 as access mode to avoid admin permission.
|
||||||
|
mode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE)
|
||||||
|
f, err = windows.CreateFile(
|
||||||
|
windows.StringToUTF16Ptr(`\\.\`+rootDrive),
|
||||||
|
0, mode, nil, windows.OPEN_EXISTING, uint32(windows.FILE_ATTRIBUTE_READONLY), 0)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer windows.Close(f)
|
||||||
|
|
||||||
|
controlCode := uint32(5636096) // IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
|
||||||
|
volumeDiskExtents := make([]byte, 16*1024)
|
||||||
|
|
||||||
|
var bytesReturned uint32
|
||||||
|
err = windows.DeviceIoControl(f, controlCode, nil, 0, &volumeDiskExtents[0], uint32(len(volumeDiskExtents)), &bytesReturned, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("could not identify physical drive for %s: %w", rootDrive, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
numDiskIDs := uint(binary.LittleEndian.Uint32(volumeDiskExtents))
|
||||||
|
if numDiskIDs < 1 {
|
||||||
|
return "", fmt.Errorf("could not identify physical drive for %s: no disk IDs returned", rootDrive)
|
||||||
|
}
|
||||||
|
|
||||||
|
diskIDs := make([]string, numDiskIDs)
|
||||||
|
|
||||||
|
for i := range numDiskIDs {
|
||||||
|
diskIDs[i] = strconv.FormatUint(uint64(binary.LittleEndian.Uint32(volumeDiskExtents[8+i*diskExtentSize:])), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.Sort(diskIDs)
|
||||||
|
diskIDs = slices.Compact(diskIDs)
|
||||||
|
|
||||||
|
return strings.Join(diskIDs, ";"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getVolumeInfo(rootDrive string) (volumeInfo, error) {
|
||||||
|
if !strings.HasSuffix(rootDrive, ":") {
|
||||||
|
return volumeInfo{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
volPath := windows.StringToUTF16Ptr(rootDrive + `\`)
|
||||||
|
|
||||||
|
volBufLabel := make([]uint16, windows.MAX_PATH+1)
|
||||||
|
volSerialNum := uint32(0)
|
||||||
|
fsFlags := uint32(0)
|
||||||
|
volBufType := make([]uint16, windows.MAX_PATH+1)
|
||||||
|
|
||||||
|
driveType := windows.GetDriveType(volPath)
|
||||||
|
|
||||||
|
err := windows.GetVolumeInformation(volPath, &volBufLabel[0], uint32(len(volBufLabel)),
|
||||||
|
&volSerialNum, nil, &fsFlags, &volBufType[0], uint32(len(volBufType)))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if driveType != windows.DRIVE_CDROM && driveType != windows.DRIVE_REMOVABLE {
|
||||||
|
return volumeInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return volumeInfo{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return volumeInfo{
|
||||||
|
volumeType: getDriveType(driveType),
|
||||||
|
label: windows.UTF16PtrToString(&volBufLabel[0]),
|
||||||
|
filesystem: windows.UTF16PtrToString(&volBufType[0]),
|
||||||
|
serialNumber: fmt.Sprintf("%X", volSerialNum),
|
||||||
|
readonly: float64(fsFlags & windows.FILE_READ_ONLY_VOLUME),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting user metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting user metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -75,14 +75,14 @@ type Win32_LogonSession struct {
|
|||||||
LogonType uint32
|
LogonType uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_LogonSession
|
var dst []Win32_LogonSession
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init counters
|
// Init counters
|
||||||
@@ -221,5 +221,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
float64(cachedunlock),
|
float64(cachedunlock),
|
||||||
"cached_unlock",
|
"cached_unlock",
|
||||||
)
|
)
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/fsrmquota"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/fsrmquota"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/hyperv"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/iis"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/license"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/logical_disk"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/logon"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/memory"
|
||||||
@@ -39,11 +40,13 @@ import (
|
|||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/nps"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/nps"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/os"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/os"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/physical_disk"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/physical_disk"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/printer"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/process"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/process"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/remote_fx"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/remote_fx"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/scheduled_task"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/scheduled_task"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/service"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/service"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/smb"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smb"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smbclient"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/smtp"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smtp"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/system"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/system"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/collector/tcp"
|
"github.com/prometheus-community/windows_exporter/pkg/collector/tcp"
|
||||||
@@ -76,6 +79,7 @@ var Map = map[string]types.CollectorBuilderWithFlags{
|
|||||||
fsrmquota.Name: fsrmquota.NewWithFlags,
|
fsrmquota.Name: fsrmquota.NewWithFlags,
|
||||||
hyperv.Name: hyperv.NewWithFlags,
|
hyperv.Name: hyperv.NewWithFlags,
|
||||||
iis.Name: iis.NewWithFlags,
|
iis.Name: iis.NewWithFlags,
|
||||||
|
license.Name: license.NewWithFlags,
|
||||||
logical_disk.Name: logical_disk.NewWithFlags,
|
logical_disk.Name: logical_disk.NewWithFlags,
|
||||||
logon.Name: logon.NewWithFlags,
|
logon.Name: logon.NewWithFlags,
|
||||||
memory.Name: memory.NewWithFlags,
|
memory.Name: memory.NewWithFlags,
|
||||||
@@ -98,11 +102,13 @@ var Map = map[string]types.CollectorBuilderWithFlags{
|
|||||||
nps.Name: nps.NewWithFlags,
|
nps.Name: nps.NewWithFlags,
|
||||||
os.Name: os.NewWithFlags,
|
os.Name: os.NewWithFlags,
|
||||||
physical_disk.Name: physical_disk.NewWithFlags,
|
physical_disk.Name: physical_disk.NewWithFlags,
|
||||||
|
printer.Name: printer.NewWithFlags,
|
||||||
process.Name: process.NewWithFlags,
|
process.Name: process.NewWithFlags,
|
||||||
remote_fx.Name: remote_fx.NewWithFlags,
|
remote_fx.Name: remote_fx.NewWithFlags,
|
||||||
scheduled_task.Name: scheduled_task.NewWithFlags,
|
scheduled_task.Name: scheduled_task.NewWithFlags,
|
||||||
service.Name: service.NewWithFlags,
|
service.Name: service.NewWithFlags,
|
||||||
smb.Name: smb.NewWithFlags,
|
smb.Name: smb.NewWithFlags,
|
||||||
|
smbclient.Name: smbclient.NewWithFlags,
|
||||||
smtp.Name: smtp.NewWithFlags,
|
smtp.Name: smtp.NewWithFlags,
|
||||||
system.Name: system.NewWithFlags,
|
system.Name: system.NewWithFlags,
|
||||||
teradici_pcoip.Name: teradici_pcoip.NewWithFlags,
|
teradici_pcoip.Name: teradici_pcoip.NewWithFlags,
|
||||||
|
|||||||
@@ -291,8 +291,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting memory metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting memory metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -335,10 +335,10 @@ type memory struct {
|
|||||||
WriteCopiesPersec float64 `perflib:"Write Copies/sec"`
|
WriteCopiesPersec float64 `perflib:"Write Copies/sec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []memory
|
var dst []memory
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Memory"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["Memory"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -533,5 +533,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
dst[0].WriteCopiesPersec,
|
dst[0].WriteCopiesPersec,
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ type Config struct{}
|
|||||||
|
|
||||||
var ConfigDefaults = Config{}
|
var ConfigDefaults = Config{}
|
||||||
|
|
||||||
|
// Variable used by mscluster_resource and mscluster_resourcegroup
|
||||||
|
var NodeName []string
|
||||||
|
|
||||||
// A collector is a Prometheus collector for WMI MSCluster_Node metrics
|
// A collector is a Prometheus collector for WMI MSCluster_Node metrics
|
||||||
type collector struct {
|
type collector struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
@@ -175,6 +178,8 @@ func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeName = []string{}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -274,6 +279,8 @@ func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
float64(v.StatusInformation),
|
float64(v.StatusInformation),
|
||||||
v.Name,
|
v.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NodeName = append(NodeName, v.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mscluster_resource
|
package mscluster_resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_node"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ type collector struct {
|
|||||||
IsAlivePollInterval *prometheus.Desc
|
IsAlivePollInterval *prometheus.Desc
|
||||||
LooksAlivePollInterval *prometheus.Desc
|
LooksAlivePollInterval *prometheus.Desc
|
||||||
MonitorProcessId *prometheus.Desc
|
MonitorProcessId *prometheus.Desc
|
||||||
|
OwnerNode *prometheus.Desc
|
||||||
PendingTimeout *prometheus.Desc
|
PendingTimeout *prometheus.Desc
|
||||||
ResourceClass *prometheus.Desc
|
ResourceClass *prometheus.Desc
|
||||||
RestartAction *prometheus.Desc
|
RestartAction *prometheus.Desc
|
||||||
@@ -102,6 +104,18 @@ func (c *collector) Build() error {
|
|||||||
[]string{"type", "owner_group", "name"},
|
[]string{"type", "owner_group", "name"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
c.OwnerNode = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||||
|
"The node hosting the resource. 0: Not hosted; 1: Hosted",
|
||||||
|
[]string{"type", "owner_group", "node_name", "name"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.OwnerNode = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||||
|
"The node hosting the resource. 0: Not hosted; 1: Hosted",
|
||||||
|
[]string{"type", "owner_group", "node_name", "name"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
c.PendingTimeout = prometheus.NewDesc(
|
c.PendingTimeout = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "pending_timeout"),
|
prometheus.BuildFQName(types.Namespace, Name, "pending_timeout"),
|
||||||
"Provides access to the resource's PendingTimeout property. If a resource cannot be brought online or taken offline in the number of milliseconds specified by the PendingTimeout property, the resource is forcibly terminated.",
|
"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.",
|
||||||
@@ -165,6 +179,7 @@ type MSCluster_Resource struct {
|
|||||||
Name string
|
Name string
|
||||||
Type string
|
Type string
|
||||||
OwnerGroup string
|
OwnerGroup string
|
||||||
|
OwnerNode string
|
||||||
|
|
||||||
Characteristics uint
|
Characteristics uint
|
||||||
DeadlockTimeout uint
|
DeadlockTimeout uint
|
||||||
@@ -244,6 +259,21 @@ func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
v.Type, v.OwnerGroup, v.Name,
|
v.Type, v.OwnerGroup, v.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if mscluster_node.NodeName != nil {
|
||||||
|
for _, node_name := range mscluster_node.NodeName {
|
||||||
|
isCurrentState := 0.0
|
||||||
|
if v.OwnerNode == node_name {
|
||||||
|
isCurrentState = 1.0
|
||||||
|
}
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.OwnerNode,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
isCurrentState,
|
||||||
|
v.Type, v.OwnerGroup, node_name, v.Name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PendingTimeout,
|
c.PendingTimeout,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mscluster_resourcegroup
|
package mscluster_resourcegroup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/mscluster_node"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ type collector struct {
|
|||||||
Flags *prometheus.Desc
|
Flags *prometheus.Desc
|
||||||
GroupType *prometheus.Desc
|
GroupType *prometheus.Desc
|
||||||
PlacementOptions *prometheus.Desc
|
PlacementOptions *prometheus.Desc
|
||||||
|
OwnerNode *prometheus.Desc
|
||||||
Priority *prometheus.Desc
|
Priority *prometheus.Desc
|
||||||
ResiliencyPeriod *prometheus.Desc
|
ResiliencyPeriod *prometheus.Desc
|
||||||
State *prometheus.Desc
|
State *prometheus.Desc
|
||||||
@@ -119,6 +121,18 @@ func (c *collector) Build() error {
|
|||||||
[]string{"name"},
|
[]string{"name"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
c.OwnerNode = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||||
|
"The node hosting the resource group. 0: Not hosted; 1: Hosted",
|
||||||
|
[]string{"node_name", "name"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.OwnerNode = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "owner_node"),
|
||||||
|
"The node hosting the resource group. 0: Not hosted; 1: Hosted",
|
||||||
|
[]string{"node_name", "name"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
c.Priority = prometheus.NewDesc(
|
c.Priority = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "priority"),
|
prometheus.BuildFQName(types.Namespace, Name, "priority"),
|
||||||
"Priority value of the resource group",
|
"Priority value of the resource group",
|
||||||
@@ -155,6 +169,7 @@ type MSCluster_ResourceGroup struct {
|
|||||||
FailoverThreshold uint
|
FailoverThreshold uint
|
||||||
Flags uint
|
Flags uint
|
||||||
GroupType uint
|
GroupType uint
|
||||||
|
OwnerNode string
|
||||||
Priority uint
|
Priority uint
|
||||||
ResiliencyPeriod uint
|
ResiliencyPeriod uint
|
||||||
State uint
|
State uint
|
||||||
@@ -241,6 +256,21 @@ func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
v.Name,
|
v.Name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if mscluster_node.NodeName != nil {
|
||||||
|
for _, node_name := range mscluster_node.NodeName {
|
||||||
|
isCurrentState := 0.0
|
||||||
|
if v.OwnerNode == node_name {
|
||||||
|
isCurrentState = 1.0
|
||||||
|
}
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.OwnerNode,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
isCurrentState,
|
||||||
|
node_name, v.Name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.Priority,
|
c.Priority,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
|
|||||||
@@ -106,8 +106,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting msmq metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting msmq metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -122,11 +122,11 @@ type Win32_PerfRawData_MSMQ_MSMQQueue struct {
|
|||||||
MessagesinQueue uint64
|
MessagesinQueue uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_MSMQ_MSMQQueue
|
var dst []Win32_PerfRawData_MSMQ_MSMQQueue
|
||||||
q := wmi.QueryAllWhere(&dst, *c.queryWhereClause, c.logger)
|
q := wmi.QueryAllWhere(&dst, *c.queryWhereClause, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, msmq := range dst {
|
for _, msmq := range dst {
|
||||||
@@ -158,5 +158,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
strings.ToLower(msmq.Name),
|
strings.ToLower(msmq.Name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1932,7 +1932,7 @@ func (c *collector) Build() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type mssqlCollectorFunc func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error)
|
type mssqlCollectorFunc func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error
|
||||||
|
|
||||||
func (c *collector) execute(ctx *types.ScrapeContext, name string, fn mssqlCollectorFunc, ch chan<- prometheus.Metric, sqlInstance string, wg *sync.WaitGroup) {
|
func (c *collector) execute(ctx *types.ScrapeContext, name string, fn mssqlCollectorFunc, ch chan<- prometheus.Metric, sqlInstance string, wg *sync.WaitGroup) {
|
||||||
// Reset failure counter on each scrape
|
// Reset failure counter on each scrape
|
||||||
@@ -1940,7 +1940,7 @@ func (c *collector) execute(ctx *types.ScrapeContext, name string, fn mssqlColle
|
|||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
begin := time.Now()
|
begin := time.Now()
|
||||||
_, err := fn(ctx, ch, sqlInstance)
|
err := fn(ctx, ch, sqlInstance)
|
||||||
duration := time.Since(begin)
|
duration := time.Since(begin)
|
||||||
var success float64
|
var success float64
|
||||||
|
|
||||||
@@ -2038,12 +2038,12 @@ type mssqlAccessMethods struct {
|
|||||||
WorktablesFromCacheRatio_Base float64 `perflib:"Worktables From Cache Base_Base"`
|
WorktablesFromCacheRatio_Base float64 `perflib:"Worktables From Cache Base_Base"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectAccessMethods(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectAccessMethods(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlAccessMethods
|
var dst []mssqlAccessMethods
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_accessmethods collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_accessmethods collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "accessmethods")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "accessmethods")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -2355,7 +2355,7 @@ func (c *collector) collectAccessMethods(ctx *types.ScrapeContext, ch chan<- pro
|
|||||||
sqlInstance,
|
sqlInstance,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerAvailabilityReplica docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerAvailabilityReplica docs:
|
||||||
@@ -2373,12 +2373,12 @@ type mssqlAvailabilityReplica struct {
|
|||||||
SendstoTransportPersec float64 `perflib:"Sends to Transport/sec"`
|
SendstoTransportPersec float64 `perflib:"Sends to Transport/sec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectAvailabilityReplica(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectAvailabilityReplica(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlAvailabilityReplica
|
var dst []mssqlAvailabilityReplica
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_availreplica collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_availreplica collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "availreplica")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "availreplica")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -2450,7 +2450,7 @@ func (c *collector) collectAvailabilityReplica(ctx *types.ScrapeContext, ch chan
|
|||||||
sqlInstance, replicaName,
|
sqlInstance, replicaName,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerBufferManager docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerBufferManager docs:
|
||||||
@@ -2481,12 +2481,12 @@ type mssqlBufferManager struct {
|
|||||||
Targetpages float64 `perflib:"Target pages"`
|
Targetpages float64 `perflib:"Target pages"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectBufferManager(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectBufferManager(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlBufferManager
|
var dst []mssqlBufferManager
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_bufman collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_bufman collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "bufman")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "bufman")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -2652,7 +2652,7 @@ func (c *collector) collectBufferManager(ctx *types.ScrapeContext, ch chan<- pro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerDatabaseReplica docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerDatabaseReplica docs:
|
||||||
@@ -2685,12 +2685,12 @@ type mssqlDatabaseReplica struct {
|
|||||||
TransactionDelay float64 `perflib:"Transaction Delay"`
|
TransactionDelay float64 `perflib:"Transaction Delay"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectDatabaseReplica(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectDatabaseReplica(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlDatabaseReplica
|
var dst []mssqlDatabaseReplica
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_dbreplica collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_dbreplica collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "dbreplica")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "dbreplica")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -2867,7 +2867,7 @@ func (c *collector) collectDatabaseReplica(ctx *types.ScrapeContext, ch chan<- p
|
|||||||
sqlInstance, replicaName,
|
sqlInstance, replicaName,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerDatabases docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerDatabases docs:
|
||||||
@@ -2924,12 +2924,12 @@ type mssqlDatabases struct {
|
|||||||
XTPMemoryUsedKB float64 `perflib:"XTP Memory Used (KB)"`
|
XTPMemoryUsedKB float64 `perflib:"XTP Memory Used (KB)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectDatabases(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectDatabases(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlDatabases
|
var dst []mssqlDatabases
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_databases collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_databases collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "databases")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "databases")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -3274,7 +3274,7 @@ func (c *collector) collectDatabases(ctx *types.ScrapeContext, ch chan<- prometh
|
|||||||
sqlInstance, dbName,
|
sqlInstance, dbName,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerGeneralStatistics docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerGeneralStatistics docs:
|
||||||
@@ -3306,12 +3306,12 @@ type mssqlGeneralStatistics struct {
|
|||||||
UserConnections float64 `perflib:"User Connections"`
|
UserConnections float64 `perflib:"User Connections"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectGeneralStatistics(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectGeneralStatistics(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlGeneralStatistics
|
var dst []mssqlGeneralStatistics
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_genstats collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_genstats collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "genstats")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "genstats")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -3484,7 +3484,7 @@ func (c *collector) collectGeneralStatistics(ctx *types.ScrapeContext, ch chan<-
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerLocks docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerLocks docs:
|
||||||
@@ -3501,12 +3501,12 @@ type mssqlLocks struct {
|
|||||||
NumberofDeadlocksPersec float64 `perflib:"Number of Deadlocks/sec"`
|
NumberofDeadlocksPersec float64 `perflib:"Number of Deadlocks/sec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectLocks(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectLocks(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlLocks
|
var dst []mssqlLocks
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_locks collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_locks collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "locks")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "locks")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -3571,7 +3571,7 @@ func (c *collector) collectLocks(ctx *types.ScrapeContext, ch chan<- prometheus.
|
|||||||
sqlInstance, lockResourceName,
|
sqlInstance, lockResourceName,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerMemoryManager docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerMemoryManager docs:
|
||||||
@@ -3599,12 +3599,12 @@ type mssqlMemoryManager struct {
|
|||||||
TotalServerMemoryKB float64 `perflib:"Total Server Memory (KB)"`
|
TotalServerMemoryKB float64 `perflib:"Total Server Memory (KB)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectMemoryManager(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectMemoryManager(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlMemoryManager
|
var dst []mssqlMemoryManager
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_memmgr collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_memmgr collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "memmgr")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "memmgr")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -3749,7 +3749,7 @@ func (c *collector) collectMemoryManager(ctx *types.ScrapeContext, ch chan<- pro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerSQLStatistics docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerSQLStatistics docs:
|
||||||
@@ -3768,12 +3768,12 @@ type mssqlSQLStatistics struct {
|
|||||||
UnsafeAutoParamsPersec float64 `perflib:"Unsafe Auto-Params/sec"`
|
UnsafeAutoParamsPersec float64 `perflib:"Unsafe Auto-Params/sec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectSQLStats(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectSQLStats(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlSQLStatistics
|
var dst []mssqlSQLStatistics
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_sqlstats collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_sqlstats collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlstats")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlstats")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -3855,7 +3855,7 @@ func (c *collector) collectSQLStats(ctx *types.ScrapeContext, ch chan<- promethe
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerWaitStatistics docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerWaitStatistics docs:
|
||||||
@@ -3876,12 +3876,12 @@ type mssqlWaitStatistics struct {
|
|||||||
WaitStatsTransactionOwnershipWaits float64 `perflib:"Transaction ownership waits"`
|
WaitStatsTransactionOwnershipWaits float64 `perflib:"Transaction ownership waits"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectWaitStats(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectWaitStats(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlWaitStatistics
|
var dst []mssqlWaitStatistics
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_waitstats collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_waitstats collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "waitstats")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "waitstats")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -3972,7 +3972,7 @@ func (c *collector) collectWaitStats(ctx *types.ScrapeContext, ch chan<- prometh
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type mssqlSQLErrors struct {
|
type mssqlSQLErrors struct {
|
||||||
@@ -3982,12 +3982,12 @@ type mssqlSQLErrors struct {
|
|||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_SQLServerErrors docs:
|
// Win32_PerfRawData_MSSQLSERVER_SQLServerErrors docs:
|
||||||
// - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-sql-errors-object
|
// - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-sql-errors-object
|
||||||
func (c *collector) collectSQLErrors(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectSQLErrors(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlSQLErrors
|
var dst []mssqlSQLErrors
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_sqlerrors collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_sqlerrors collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlerrors")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "sqlerrors")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -4004,7 +4004,7 @@ func (c *collector) collectSQLErrors(ctx *types.ScrapeContext, ch chan<- prometh
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type mssqlTransactions struct {
|
type mssqlTransactions struct {
|
||||||
@@ -4025,12 +4025,12 @@ type mssqlTransactions struct {
|
|||||||
|
|
||||||
// Win32_PerfRawData_MSSQLSERVER_Transactions docs:
|
// Win32_PerfRawData_MSSQLSERVER_Transactions docs:
|
||||||
// - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-transactions-object
|
// - https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-transactions-object
|
||||||
func (c *collector) collectTransactions(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) (*prometheus.Desc, error) {
|
func (c *collector) collectTransactions(ctx *types.ScrapeContext, ch chan<- prometheus.Metric, sqlInstance string) error {
|
||||||
var dst []mssqlTransactions
|
var dst []mssqlTransactions
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_transactions collector iterating sql instance %s.", sqlInstance))
|
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("mssql_transactions collector iterating sql instance %s.", sqlInstance))
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "transactions")], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects[mssqlGetPerfObjectName(sqlInstance, "transactions")], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range dst {
|
for _, v := range dst {
|
||||||
@@ -4126,5 +4126,5 @@ func (c *collector) collectTransactions(ctx *types.ScrapeContext, ch chan<- prom
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,8 +196,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting net metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting net metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -228,11 +228,11 @@ type networkInterface struct {
|
|||||||
CurrentBandwidth float64 `perflib:"Current Bandwidth"`
|
CurrentBandwidth float64 `perflib:"Current Bandwidth"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []networkInterface
|
var dst []networkInterface
|
||||||
|
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Network Interface"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["Network Interface"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, nic := range dst {
|
for _, nic := range dst {
|
||||||
@@ -326,5 +326,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrexceptions metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrexceptions metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -98,11 +98,11 @@ type Win32_PerfRawData_NETFramework_NETCLRExceptions struct {
|
|||||||
ThrowToCatchDepthPersec uint32
|
ThrowToCatchDepthPersec uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRExceptions
|
var dst []Win32_PerfRawData_NETFramework_NETCLRExceptions
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -140,5 +140,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrinterop metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrinterop metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -91,11 +91,11 @@ type Win32_PerfRawData_NETFramework_NETCLRInterop struct {
|
|||||||
NumberofTLBimportsPersec uint32
|
NumberofTLBimportsPersec uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRInterop
|
var dst []Win32_PerfRawData_NETFramework_NETCLRInterop
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -126,5 +126,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrjit metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrjit metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -99,11 +99,11 @@ type Win32_PerfRawData_NETFramework_NETCLRJit struct {
|
|||||||
TotalNumberofILBytesJitted uint32
|
TotalNumberofILBytesJitted uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRJit
|
var dst []Win32_PerfRawData_NETFramework_NETCLRJit
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -141,5 +141,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrloading metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrloading metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -143,11 +143,11 @@ type Win32_PerfRawData_NETFramework_NETCLRLoading struct {
|
|||||||
TotalNumberofLoadFailures uint32
|
TotalNumberofLoadFailures uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLoading
|
var dst []Win32_PerfRawData_NETFramework_NETCLRLoading
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -220,5 +220,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrlocksandthreads metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrlocksandthreads metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -123,11 +123,11 @@ type Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads struct {
|
|||||||
TotalNumberofContentions uint32
|
TotalNumberofContentions uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads
|
var dst []Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -186,5 +186,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,8 +139,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrmemory metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrmemory metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -180,11 +180,11 @@ type Win32_PerfRawData_NETFramework_NETCLRMemory struct {
|
|||||||
PromotedMemoryfromGen1 uint64
|
PromotedMemoryfromGen1 uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRMemory
|
var dst []Win32_PerfRawData_NETFramework_NETCLRMemory
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -329,5 +329,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrremoting metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrremoting metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -113,11 +113,11 @@ type Win32_PerfRawData_NETFramework_NETCLRRemoting struct {
|
|||||||
TotalRemoteCalls uint32
|
TotalRemoteCalls uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRRemoting
|
var dst []Win32_PerfRawData_NETFramework_NETCLRRemoting
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -169,5 +169,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting win32_perfrawdata_netframework_netclrsecurity metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting win32_perfrawdata_netframework_netclrsecurity metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -98,11 +98,11 @@ type Win32_PerfRawData_NETFramework_NETCLRSecurity struct {
|
|||||||
TotalRuntimeChecks uint32
|
TotalRuntimeChecks uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_NETFramework_NETCLRSecurity
|
var dst []Win32_PerfRawData_NETFramework_NETCLRSecurity
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range dst {
|
for _, process := range dst {
|
||||||
@@ -140,5 +140,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,12 +229,12 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.CollectAccept(ch); err != nil {
|
if err := c.CollectAccept(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accept data: %s %v", desc, err))
|
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accept data: %s", err))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.CollectAccounting(ch); err != nil {
|
if err := c.CollectAccounting(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accounting data: %s %v", desc, err))
|
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accounting data: %s", err))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -279,11 +279,11 @@ type Win32_PerfRawData_IAS_NPSAccountingServer struct {
|
|||||||
|
|
||||||
// CollectAccept sends the metric values for each metric
|
// CollectAccept sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) CollectAccept(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) CollectAccept(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_IAS_NPSAuthenticationServer
|
var dst []Win32_PerfRawData_IAS_NPSAuthenticationServer
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -364,14 +364,14 @@ func (c *collector) CollectAccept(ch chan<- prometheus.Metric) (*prometheus.Desc
|
|||||||
float64(dst[0].AccessUnknownType),
|
float64(dst[0].AccessUnknownType),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) CollectAccounting(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) CollectAccounting(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_IAS_NPSAccountingServer
|
var dst []Win32_PerfRawData_IAS_NPSAccountingServer
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -446,5 +446,5 @@ func (c *collector) CollectAccounting(ch chan<- prometheus.Metric) (*prometheus.
|
|||||||
float64(dst[0].AccountingUnknownType),
|
float64(dst[0].AccountingUnknownType),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,19 +3,24 @@
|
|||||||
package os
|
package os
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/kernel32"
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/go-kit/log/level"
|
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/headers/netapi32"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/netapi32"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/headers/psapi"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/psapi"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
|
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
|
|
||||||
|
"github.com/alecthomas/kingpin/v2"
|
||||||
|
"github.com/go-kit/log"
|
||||||
|
"github.com/go-kit/log/level"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"golang.org/x/sys/windows/registry"
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
@@ -158,8 +163,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting os metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting os metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -183,50 +188,35 @@ type Win32_OperatingSystem struct {
|
|||||||
Version string
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
nwgi, err := netapi32.GetWorkstationInfo()
|
nwgi, err := netapi32.GetWorkstationInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gmse, err := sysinfoapi.GlobalMemoryStatusEx()
|
gmse, err := sysinfoapi.GlobalMemoryStatusEx()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
timezoneName, _ := currentTime.Zone()
|
|
||||||
|
timeZoneInfo, err := kernel32.GetDynamicTimeZoneInformation()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeZoneKeyName contains the english name of the timezone.
|
||||||
|
timezoneName := syscall.UTF16ToString(timeZoneInfo.TimeZoneKeyName[:])
|
||||||
|
|
||||||
// Get total allocation of paging files across all disks.
|
// Get total allocation of paging files across all disks.
|
||||||
memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE)
|
memManKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management`, registry.QUERY_VALUE)
|
||||||
defer memManKey.Close()
|
defer memManKey.Close()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
|
pagingFiles, _, pagingErr := memManKey.GetStringsValue("ExistingPageFiles")
|
||||||
// Get build number and product name from registry
|
|
||||||
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
|
||||||
defer ntKey.Close()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pn, _, err := ntKey.GetStringValue("ProductName")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
bn, _, err := ntKey.GetStringValue("CurrentBuildNumber")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
revision, _, err := ntKey.GetIntegerValue("UBR")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var fsipf float64
|
var fsipf float64
|
||||||
for _, pagingFile := range pagingFiles {
|
for _, pagingFile := range pagingFiles {
|
||||||
@@ -240,14 +230,39 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get build number and product name from registry
|
||||||
|
ntKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||||
|
defer ntKey.Close()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pn, _, err := ntKey.GetStringValue("ProductName")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
bn, _, err := ntKey.GetStringValue("CurrentBuildNumber")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
revision, _, err := ntKey.GetIntegerValue("UBR")
|
||||||
|
if errors.Is(err, registry.ErrNotExist) {
|
||||||
|
revision = 0
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
gpi, err := psapi.GetPerformanceInfo()
|
gpi, err := psapi.GetPerformanceInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pfc := make([]pagingFileCounter, 0)
|
pfc := make([]pagingFileCounter, 0)
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Paging File"], &pfc, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["Paging File"], &pfc, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current page file usage.
|
// Get current page file usage.
|
||||||
@@ -266,12 +281,12 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
c.OSInformation,
|
c.OSInformation,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
1.0,
|
1.0,
|
||||||
fmt.Sprintf("Microsoft %s", pn), // Caption
|
"Microsoft "+pn, // Caption
|
||||||
fmt.Sprintf("%d.%d.%s", nwgi.VersionMajor, nwgi.VersionMinor, bn), // Version
|
fmt.Sprintf("%d.%d.%s", nwgi.VersionMajor, nwgi.VersionMinor, bn), // Version
|
||||||
fmt.Sprintf("%d", nwgi.VersionMajor), // Major Version
|
strconv.FormatUint(uint64(nwgi.VersionMajor), 10), // Major Version
|
||||||
fmt.Sprintf("%d", nwgi.VersionMinor), // Minor Version
|
strconv.FormatUint(uint64(nwgi.VersionMinor), 10), // Minor Version
|
||||||
bn, // Build number
|
bn, // Build number
|
||||||
fmt.Sprintf("%d", revision), // Revision
|
strconv.FormatUint(revision, 10), // Revision
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -306,7 +321,7 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
fsipf,
|
fsipf,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
_ = level.Debug(c.logger).Log("Could not find HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management key. windows_os_paging_free_bytes and windows_os_paging_limit_bytes will be omitted.")
|
_ = level.Debug(c.logger).Log("msg", "Could not find HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management key. windows_os_paging_free_bytes and windows_os_paging_limit_bytes will be omitted.")
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.VirtualMemoryFreeBytes,
|
c.VirtualMemoryFreeBytes,
|
||||||
@@ -353,5 +368,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
float64(gmse.TotalPhys),
|
float64(gmse.TotalPhys),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,8 +206,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting physical_disk metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting physical_disk metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -232,10 +232,10 @@ type PhysicalDisk struct {
|
|||||||
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
|
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []PhysicalDisk
|
var dst []PhysicalDisk
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["PhysicalDisk"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["PhysicalDisk"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, disk := range dst {
|
for _, disk := range dst {
|
||||||
@@ -334,5 +334,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
227
pkg/collector/printer/printer.go
Normal file
227
pkg/collector/printer/printer.go
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package printer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alecthomas/kingpin/v2"
|
||||||
|
"github.com/go-kit/log"
|
||||||
|
"github.com/go-kit/log/level"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Name = "printer"
|
||||||
|
|
||||||
|
FlagPrinterInclude = "collector.printer.include"
|
||||||
|
FlagPrinterExclude = "collector.printer.exclude"
|
||||||
|
)
|
||||||
|
|
||||||
|
// printerStatusMap source: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-printer#:~:text=Power%20Save-,PrinterStatus,Offline%20(7),-PrintJobDataType
|
||||||
|
var printerStatusMap = map[uint16]string{
|
||||||
|
1: "Other",
|
||||||
|
2: "Unknown",
|
||||||
|
3: "Idle",
|
||||||
|
4: "Printing",
|
||||||
|
5: "Warmup",
|
||||||
|
6: "Stopped Printing",
|
||||||
|
7: "Offline",
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Include string `yaml:"printer_include"`
|
||||||
|
Exclude string `yaml:"printer_exclude"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var ConfigDefaults = Config{
|
||||||
|
Include: ".+",
|
||||||
|
Exclude: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
type collector struct {
|
||||||
|
logger log.Logger
|
||||||
|
|
||||||
|
printerInclude *string
|
||||||
|
printerExclude *string
|
||||||
|
|
||||||
|
printerStatus *prometheus.Desc
|
||||||
|
printerJobStatus *prometheus.Desc
|
||||||
|
printerJobCount *prometheus.Desc
|
||||||
|
|
||||||
|
printerIncludePattern *regexp.Regexp
|
||||||
|
printerExcludePattern *regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(logger log.Logger, config *Config) types.Collector {
|
||||||
|
if config == nil {
|
||||||
|
config = &ConfigDefaults
|
||||||
|
}
|
||||||
|
c := &collector{
|
||||||
|
printerInclude: &config.Include,
|
||||||
|
printerExclude: &config.Exclude,
|
||||||
|
}
|
||||||
|
c.SetLogger(logger)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithFlags(app *kingpin.Application) types.Collector {
|
||||||
|
c := &collector{
|
||||||
|
printerInclude: app.Flag(
|
||||||
|
FlagPrinterInclude,
|
||||||
|
"Regular expression to match printers to collect metrics for",
|
||||||
|
).Default(ConfigDefaults.Include).String(),
|
||||||
|
printerExclude: app.Flag(
|
||||||
|
FlagPrinterExclude,
|
||||||
|
"Regular expression to match printers to exclude",
|
||||||
|
).Default(ConfigDefaults.Exclude).String(),
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) SetLogger(logger log.Logger) {
|
||||||
|
c.logger = log.With(logger, "collector", Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) Build() error {
|
||||||
|
c.printerJobStatus = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "job_status"),
|
||||||
|
"A counter of printer jobs by status",
|
||||||
|
[]string{"printer", "status"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.printerStatus = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "status"),
|
||||||
|
"Printer status",
|
||||||
|
[]string{"printer", "status"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.printerJobCount = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "job_count"),
|
||||||
|
"Number of jobs processed by the printer since the last reset",
|
||||||
|
[]string{"printer"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
c.printerIncludePattern, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", *c.printerInclude))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.printerExcludePattern, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", *c.printerExclude))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) GetName() string { return Name }
|
||||||
|
|
||||||
|
func (c *collector) GetPerfCounter() ([]string, error) { return []string{"Printer"}, nil }
|
||||||
|
|
||||||
|
type win32_Printer struct {
|
||||||
|
Name string
|
||||||
|
Default bool
|
||||||
|
PrinterStatus uint16
|
||||||
|
JobCountSinceLastReset uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type win32_PrintJob struct {
|
||||||
|
Name string
|
||||||
|
Status string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
|
if err := c.collectPrinterStatus(ch); err != nil {
|
||||||
|
_ = level.Error(c.logger).Log("msg", "failed to collect printer status metrics", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := c.collectPrinterJobStatus(ch); err != nil {
|
||||||
|
_ = level.Error(c.logger).Log("msg", "failed to collect printer job status metrics", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) collectPrinterStatus(ch chan<- prometheus.Metric) error {
|
||||||
|
var printers []win32_Printer
|
||||||
|
q := wmi.QueryAll(&printers, c.logger)
|
||||||
|
if err := wmi.Query(q, &printers); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, printer := range printers {
|
||||||
|
if c.printerExcludePattern.MatchString(printer.Name) ||
|
||||||
|
!c.printerIncludePattern.MatchString(printer.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for printerStatus, printerStatusName := range printerStatusMap {
|
||||||
|
isCurrentStatus := 0.0
|
||||||
|
if printerStatus == printer.PrinterStatus {
|
||||||
|
isCurrentStatus = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.printerStatus,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
isCurrentStatus,
|
||||||
|
printer.Name,
|
||||||
|
printerStatusName,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.printerJobCount,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
float64(printer.JobCountSinceLastReset),
|
||||||
|
printer.Name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) collectPrinterJobStatus(ch chan<- prometheus.Metric) error {
|
||||||
|
var printJobs []win32_PrintJob
|
||||||
|
q := wmi.QueryAll(&printJobs, c.logger)
|
||||||
|
if err := wmi.Query(q, &printJobs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
groupedPrintJobs := c.groupPrintJobs(printJobs)
|
||||||
|
for group, count := range groupedPrintJobs {
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.printerJobStatus,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
float64(count),
|
||||||
|
group.printerName,
|
||||||
|
group.status,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrintJobStatusGroup struct {
|
||||||
|
printerName string
|
||||||
|
status string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) groupPrintJobs(printJobs []win32_PrintJob) map[PrintJobStatusGroup]int {
|
||||||
|
groupedPrintJobs := make(map[PrintJobStatusGroup]int)
|
||||||
|
for _, printJob := range printJobs {
|
||||||
|
printerName := strings.Split(printJob.Name, ",")[0]
|
||||||
|
|
||||||
|
if c.printerExcludePattern.MatchString(printerName) ||
|
||||||
|
!c.printerIncludePattern.MatchString(printerName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
groupedPrintJobs[PrintJobStatusGroup{
|
||||||
|
printerName: printerName,
|
||||||
|
status: printJob.Status,
|
||||||
|
}]++
|
||||||
|
}
|
||||||
|
return groupedPrintJobs
|
||||||
|
}
|
||||||
17
pkg/collector/printer/printer_test.go
Normal file
17
pkg/collector/printer/printer_test.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package printer_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alecthomas/kingpin/v2"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/printer"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkCollector(b *testing.B) {
|
||||||
|
// Whitelist is not set in testing context (kingpin flags not parsed), causing the collector to skip all printers.
|
||||||
|
printersInclude := ".+"
|
||||||
|
kingpin.CommandLine.GetArg(printer.FlagPrinterInclude).StringVar(&printersInclude)
|
||||||
|
testutils.FuncBenchmarkCollector(b, "printer", printer.NewWithFlags)
|
||||||
|
}
|
||||||
@@ -3,10 +3,13 @@
|
|||||||
package process
|
package process
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
@@ -19,21 +22,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Name = "process"
|
Name = "process"
|
||||||
FlagProcessExclude = "collector.process.exclude"
|
FlagProcessExclude = "collector.process.exclude"
|
||||||
FlagProcessInclude = "collector.process.include"
|
FlagProcessInclude = "collector.process.include"
|
||||||
|
FlagEnableWorkerProcess = "collector.process.iis"
|
||||||
|
FlagEnableReportOwner = "collector.process.report-owner"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ProcessInclude string `yaml:"process_include"`
|
ProcessInclude string `yaml:"process_include"`
|
||||||
ProcessExclude string `yaml:"process_exclude"`
|
ProcessExclude string `yaml:"process_exclude"`
|
||||||
EnableWorkerProcess bool `yaml:"enable_iis_worker_process"`
|
EnableWorkerProcess bool `yaml:"enable_iis_worker_process"`
|
||||||
|
EnableReportOwner bool `yaml:"enable_report_owner"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConfigDefaults = Config{
|
var ConfigDefaults = Config{
|
||||||
ProcessInclude: ".+",
|
ProcessInclude: ".+",
|
||||||
ProcessExclude: "",
|
ProcessExclude: "",
|
||||||
EnableWorkerProcess: false,
|
EnableWorkerProcess: false,
|
||||||
|
EnableReportOwner: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
type collector struct {
|
type collector struct {
|
||||||
@@ -43,6 +50,7 @@ type collector struct {
|
|||||||
processExclude *string
|
processExclude *string
|
||||||
|
|
||||||
enableWorkerProcess *bool
|
enableWorkerProcess *bool
|
||||||
|
enableReportOwner *bool
|
||||||
|
|
||||||
StartTime *prometheus.Desc
|
StartTime *prometheus.Desc
|
||||||
CPUTimeTotal *prometheus.Desc
|
CPUTimeTotal *prometheus.Desc
|
||||||
@@ -62,6 +70,8 @@ type collector struct {
|
|||||||
|
|
||||||
processIncludePattern *regexp.Regexp
|
processIncludePattern *regexp.Regexp
|
||||||
processExcludePattern *regexp.Regexp
|
processExcludePattern *regexp.Regexp
|
||||||
|
|
||||||
|
lookupCache map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(logger log.Logger, config *Config) types.Collector {
|
func New(logger log.Logger, config *Config) types.Collector {
|
||||||
@@ -90,10 +100,15 @@ func NewWithFlags(app *kingpin.Application) types.Collector {
|
|||||||
"Regexp of processes to exclude. Process name must both match include and not match exclude to be included.",
|
"Regexp of processes to exclude. Process name must both match include and not match exclude to be included.",
|
||||||
).Default(ConfigDefaults.ProcessExclude).String(),
|
).Default(ConfigDefaults.ProcessExclude).String(),
|
||||||
|
|
||||||
enableWorkerProcess: kingpin.Flag(
|
enableWorkerProcess: app.Flag(
|
||||||
"collector.process.iis",
|
FlagEnableWorkerProcess,
|
||||||
"Enable IIS worker process name queries. May cause the collector to leak memory.",
|
"Enable IIS worker process name queries. May cause the collector to leak memory.",
|
||||||
).Default("false").Bool(),
|
).Default("false").Bool(),
|
||||||
|
|
||||||
|
enableReportOwner: app.Flag(
|
||||||
|
FlagEnableReportOwner,
|
||||||
|
"Enable reporting of process owner.",
|
||||||
|
).Default("false").Bool(),
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@@ -115,97 +130,104 @@ func (c *collector) Build() error {
|
|||||||
_ = level.Warn(c.logger).Log("msg", "No filters specified for process collector. This will generate a very large number of metrics!")
|
_ = level.Warn(c.logger).Log("msg", "No filters specified for process collector. This will generate a very large number of metrics!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commonLabels := make([]string, 0)
|
||||||
|
if *c.enableReportOwner {
|
||||||
|
commonLabels = []string{"owner"}
|
||||||
|
}
|
||||||
|
|
||||||
c.StartTime = prometheus.NewDesc(
|
c.StartTime = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "start_time"),
|
prometheus.BuildFQName(types.Namespace, Name, "start_time"),
|
||||||
"Time of process start.",
|
"Time of process start.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.CPUTimeTotal = prometheus.NewDesc(
|
c.CPUTimeTotal = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "cpu_time_total"),
|
prometheus.BuildFQName(types.Namespace, Name, "cpu_time_total"),
|
||||||
"Returns elapsed time that all of the threads of this process used the processor to execute instructions by mode (privileged, user).",
|
"Returns elapsed time that all of the threads of this process used the processor to execute instructions by mode (privileged, user).",
|
||||||
[]string{"process", "process_id", "creating_process_id", "mode"},
|
append(commonLabels, "process", "process_id", "creating_process_id", "mode"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.HandleCount = prometheus.NewDesc(
|
c.HandleCount = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "handles"),
|
prometheus.BuildFQName(types.Namespace, Name, "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.",
|
"Total number of handles the process has open. This number is the sum of the handles currently open by each thread in the process.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.IOBytesTotal = prometheus.NewDesc(
|
c.IOBytesTotal = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "io_bytes_total"),
|
prometheus.BuildFQName(types.Namespace, Name, "io_bytes_total"),
|
||||||
"Bytes issued to I/O operations in different modes (read, write, other).",
|
"Bytes issued to I/O operations in different modes (read, write, other).",
|
||||||
[]string{"process", "process_id", "creating_process_id", "mode"},
|
append(commonLabels, "process", "process_id", "creating_process_id", "mode"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.IOOperationsTotal = prometheus.NewDesc(
|
c.IOOperationsTotal = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "io_operations_total"),
|
prometheus.BuildFQName(types.Namespace, Name, "io_operations_total"),
|
||||||
"I/O operations issued in different modes (read, write, other).",
|
"I/O operations issued in different modes (read, write, other).",
|
||||||
[]string{"process", "process_id", "creating_process_id", "mode"},
|
append(commonLabels, "process", "process_id", "creating_process_id", "mode"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.PageFaultsTotal = prometheus.NewDesc(
|
c.PageFaultsTotal = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "page_faults_total"),
|
prometheus.BuildFQName(types.Namespace, Name, "page_faults_total"),
|
||||||
"Page faults by the threads executing in this process.",
|
"Page faults by the threads executing in this process.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.PageFileBytes = prometheus.NewDesc(
|
c.PageFileBytes = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "page_file_bytes"),
|
prometheus.BuildFQName(types.Namespace, Name, "page_file_bytes"),
|
||||||
"Current number of bytes this process has used in the paging file(s).",
|
"Current number of bytes this process has used in the paging file(s).",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.PoolBytes = prometheus.NewDesc(
|
c.PoolBytes = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "pool_bytes"),
|
prometheus.BuildFQName(types.Namespace, Name, "pool_bytes"),
|
||||||
"Pool Bytes is the last observed number of bytes in the paged or nonpaged pool.",
|
"Pool Bytes is the last observed number of bytes in the paged or nonpaged pool.",
|
||||||
[]string{"process", "process_id", "creating_process_id", "pool"},
|
append(commonLabels, "process", "process_id", "creating_process_id", "pool"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.PriorityBase = prometheus.NewDesc(
|
c.PriorityBase = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "priority_base"),
|
prometheus.BuildFQName(types.Namespace, Name, "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.",
|
"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.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.PrivateBytes = prometheus.NewDesc(
|
c.PrivateBytes = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "private_bytes"),
|
prometheus.BuildFQName(types.Namespace, Name, "private_bytes"),
|
||||||
"Current number of bytes this process has allocated that cannot be shared with other processes.",
|
"Current number of bytes this process has allocated that cannot be shared with other processes.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.ThreadCount = prometheus.NewDesc(
|
c.ThreadCount = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "threads"),
|
prometheus.BuildFQName(types.Namespace, Name, "threads"),
|
||||||
"Number of threads currently active in this process.",
|
"Number of threads currently active in this process.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.VirtualBytes = prometheus.NewDesc(
|
c.VirtualBytes = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "virtual_bytes"),
|
prometheus.BuildFQName(types.Namespace, Name, "virtual_bytes"),
|
||||||
"Current size, in bytes, of the virtual address space that the process is using.",
|
"Current size, in bytes, of the virtual address space that the process is using.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.WorkingSetPrivate = prometheus.NewDesc(
|
c.WorkingSetPrivate = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "working_set_private_bytes"),
|
prometheus.BuildFQName(types.Namespace, Name, "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.",
|
"Size of the working set, in bytes, that is use for this process only and not shared nor shareable by other processes.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.WorkingSetPeak = prometheus.NewDesc(
|
c.WorkingSetPeak = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "working_set_peak_bytes"),
|
prometheus.BuildFQName(types.Namespace, Name, "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.",
|
"Maximum size, in bytes, of the Working Set of this process at any point in time. The Working Set is the set of memory pages touched recently by the threads in the process.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.WorkingSet = prometheus.NewDesc(
|
c.WorkingSet = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "working_set_bytes"),
|
prometheus.BuildFQName(types.Namespace, Name, "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.",
|
"Maximum number of bytes in the working set of this process at any point in time. The working set is the set of memory pages touched recently by the threads in the process.",
|
||||||
[]string{"process", "process_id", "creating_process_id"},
|
append(commonLabels, "process", "process_id", "creating_process_id"),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
c.lookupCache = make(map[string]string)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
c.processIncludePattern, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", *c.processInclude))
|
c.processIncludePattern, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", *c.processInclude))
|
||||||
@@ -269,10 +291,12 @@ func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
if *c.enableWorkerProcess {
|
if *c.enableWorkerProcess {
|
||||||
q_wp := wmi.QueryAll(&dst_wp, c.logger)
|
q_wp := wmi.QueryAll(&dst_wp, c.logger)
|
||||||
if err := wmi.QueryNamespace(q_wp, &dst_wp, "root\\WebAdministration"); err != nil {
|
if err := wmi.QueryNamespace(q_wp, &dst_wp, "root\\WebAdministration"); err != nil {
|
||||||
_ = level.Debug(c.logger).Log(fmt.Sprintf("Could not query WebAdministration namespace for IIS worker processes: %v. Skipping\n", err))
|
_ = level.Debug(c.logger).Log("msg", "Could not query WebAdministration namespace for IIS worker processes", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var owner string
|
||||||
|
|
||||||
for _, process := range data {
|
for _, process := range data {
|
||||||
if process.Name == "_Total" ||
|
if process.Name == "_Total" ||
|
||||||
c.processExcludePattern.MatchString(process.Name) ||
|
c.processExcludePattern.MatchString(process.Name) ||
|
||||||
@@ -293,205 +317,204 @@ func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labels := make([]string, 0, 4)
|
||||||
|
|
||||||
|
if *c.enableReportOwner {
|
||||||
|
owner, err = c.getProcessOwner(int(process.IDProcess))
|
||||||
|
if err != nil {
|
||||||
|
owner = "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
labels = []string{owner}
|
||||||
|
}
|
||||||
|
|
||||||
|
labels = append(labels, processName, pid, cpid)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.StartTime,
|
c.StartTime,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.ElapsedTime,
|
process.ElapsedTime,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.HandleCount,
|
c.HandleCount,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.HandleCount,
|
process.HandleCount,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CPUTimeTotal,
|
c.CPUTimeTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.PercentPrivilegedTime,
|
process.PercentPrivilegedTime,
|
||||||
processName,
|
append(labels, "privileged")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"privileged",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CPUTimeTotal,
|
c.CPUTimeTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.PercentUserTime,
|
process.PercentUserTime,
|
||||||
processName,
|
append(labels, "user")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"user",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOOtherBytesPerSec,
|
process.IOOtherBytesPerSec,
|
||||||
processName,
|
append(labels, "other")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"other",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOOtherOperationsPerSec,
|
process.IOOtherOperationsPerSec,
|
||||||
processName,
|
append(labels, "other")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"other",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOReadBytesPerSec,
|
process.IOReadBytesPerSec,
|
||||||
processName,
|
append(labels, "read")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"read",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOReadOperationsPerSec,
|
process.IOReadOperationsPerSec,
|
||||||
processName,
|
append(labels, "read")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"read",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOBytesTotal,
|
c.IOBytesTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOWriteBytesPerSec,
|
process.IOWriteBytesPerSec,
|
||||||
processName,
|
append(labels, "write")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"write",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IOOperationsTotal,
|
c.IOOperationsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.IOWriteOperationsPerSec,
|
process.IOWriteOperationsPerSec,
|
||||||
processName,
|
append(labels, "write")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"write",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PageFaultsTotal,
|
c.PageFaultsTotal,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
process.PageFaultsPerSec,
|
process.PageFaultsPerSec,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PageFileBytes,
|
c.PageFileBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PageFileBytes,
|
process.PageFileBytes,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PoolBytes,
|
c.PoolBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PoolNonpagedBytes,
|
process.PoolNonpagedBytes,
|
||||||
processName,
|
append(labels, "nonpaged")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"nonpaged",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PoolBytes,
|
c.PoolBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PoolPagedBytes,
|
process.PoolPagedBytes,
|
||||||
processName,
|
append(labels, "paged")...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
"paged",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PriorityBase,
|
c.PriorityBase,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PriorityBase,
|
process.PriorityBase,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PrivateBytes,
|
c.PrivateBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.PrivateBytes,
|
process.PrivateBytes,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.ThreadCount,
|
c.ThreadCount,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.ThreadCount,
|
process.ThreadCount,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.VirtualBytes,
|
c.VirtualBytes,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.VirtualBytes,
|
process.VirtualBytes,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.WorkingSetPrivate,
|
c.WorkingSetPrivate,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.WorkingSetPrivate,
|
process.WorkingSetPrivate,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.WorkingSetPeak,
|
c.WorkingSetPeak,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.WorkingSetPeak,
|
process.WorkingSetPeak,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.WorkingSet,
|
c.WorkingSet,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
process.WorkingSet,
|
process.WorkingSet,
|
||||||
processName,
|
labels...,
|
||||||
pid,
|
|
||||||
cpid,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ref: https://github.com/microsoft/hcsshim/blob/8beabacfc2d21767a07c20f8dd5f9f3932dbf305/internal/uvm/stats.go#L25
|
||||||
|
func (c *collector) getProcessOwner(pid int) (string, error) {
|
||||||
|
p, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
|
||||||
|
if errors.Is(err, syscall.Errno(0x57)) { // invalid parameter, for PIDs that don't exist
|
||||||
|
return "", errors.New("process not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("OpenProcess: %T %w", err, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer windows.Close(p)
|
||||||
|
|
||||||
|
var tok windows.Token
|
||||||
|
if err = windows.OpenProcessToken(p, windows.TOKEN_QUERY, &tok); err != nil {
|
||||||
|
return "", fmt.Errorf("OpenProcessToken: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenUser, err := tok.GetTokenUser()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("GetTokenUser: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sid := tokenUser.User.Sid.String()
|
||||||
|
if owner, ok := c.lookupCache[sid]; ok {
|
||||||
|
return owner, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
account, domain, _, err := tokenUser.User.Sid.LookupAccount("")
|
||||||
|
if err != nil {
|
||||||
|
c.lookupCache[sid] = sid
|
||||||
|
} else {
|
||||||
|
c.lookupCache[sid] = fmt.Sprintf(`%s\%s`, account, domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.lookupCache[sid], nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ type collector struct {
|
|||||||
TotalSentBytes *prometheus.Desc
|
TotalSentBytes *prometheus.Desc
|
||||||
UDPPacketsReceivedPersec *prometheus.Desc
|
UDPPacketsReceivedPersec *prometheus.Desc
|
||||||
UDPPacketsSentPersec *prometheus.Desc
|
UDPPacketsSentPersec *prometheus.Desc
|
||||||
|
FECRate *prometheus.Desc
|
||||||
|
LossRate *prometheus.Desc
|
||||||
|
RetransmissionRate *prometheus.Desc
|
||||||
|
|
||||||
// gfx
|
// gfx
|
||||||
AverageEncodingTime *prometheus.Desc
|
AverageEncodingTime *prometheus.Desc
|
||||||
@@ -69,7 +72,7 @@ func (c *collector) SetLogger(logger log.Logger) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) GetPerfCounter() ([]string, error) {
|
func (c *collector) GetPerfCounter() ([]string, error) {
|
||||||
return []string{"RemoteFX Network"}, nil
|
return []string{"RemoteFX Network", "RemoteFX Graphics"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) Build() error {
|
func (c *collector) Build() error {
|
||||||
@@ -134,6 +137,24 @@ func (c *collector) Build() error {
|
|||||||
[]string{"session_name"},
|
[]string{"session_name"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
c.FECRate = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "net_fec_rate"),
|
||||||
|
"Forward Error Correction (FEC) percentage",
|
||||||
|
[]string{"session_name"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.LossRate = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "net_loss_rate"),
|
||||||
|
"Loss percentage",
|
||||||
|
[]string{"session_name"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.RetransmissionRate = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "net_retransmission_rate"),
|
||||||
|
"Percentage of packets that have been retransmitted",
|
||||||
|
[]string{"session_name"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
// gfx
|
// gfx
|
||||||
c.AverageEncodingTime = prometheus.NewDesc(
|
c.AverageEncodingTime = prometheus.NewDesc(
|
||||||
@@ -184,12 +205,12 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectRemoteFXNetworkCount(ctx, ch); err != nil {
|
if err := c.collectRemoteFXNetworkCount(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting terminal services session count metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectRemoteFXGraphicsCounters(ctx, ch); err != nil {
|
if err := c.collectRemoteFXGraphicsCounters(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting terminal services session count metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -207,18 +228,21 @@ type perflibRemoteFxNetwork struct {
|
|||||||
TotalSentBytes float64 `perflib:"Total Sent Bytes"`
|
TotalSentBytes float64 `perflib:"Total Sent Bytes"`
|
||||||
UDPPacketsReceivedPersec float64 `perflib:"UDP Packets Received/sec"`
|
UDPPacketsReceivedPersec float64 `perflib:"UDP Packets Received/sec"`
|
||||||
UDPPacketsSentPersec float64 `perflib:"UDP Packets Sent/sec"`
|
UDPPacketsSentPersec float64 `perflib:"UDP Packets Sent/sec"`
|
||||||
|
FECRate float64 `perflib:"Forward Error Correction (FEC) percentage"`
|
||||||
|
LossRate float64 `perflib:"Loss percentage"`
|
||||||
|
RetransmissionRate float64 `perflib:"Percentage of packets that have been retransmitted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectRemoteFXNetworkCount(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectRemoteFXNetworkCount(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
dst := make([]perflibRemoteFxNetwork, 0)
|
dst := make([]perflibRemoteFxNetwork, 0)
|
||||||
err := perflib.UnmarshalObject(ctx.PerfObjects["RemoteFX Network"], &dst, c.logger)
|
err := perflib.UnmarshalObject(ctx.PerfObjects["RemoteFX Network"], &dst, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range dst {
|
for _, d := range dst {
|
||||||
// only connect metrics for remote named sessions
|
// only connect metrics for remote named sessions
|
||||||
n := strings.ToLower(d.Name)
|
n := strings.ToLower(normalizeSessionName(d.Name))
|
||||||
if n == "" || n == "services" || n == "console" {
|
if n == "" || n == "services" || n == "console" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -226,64 +250,84 @@ func (c *collector) collectRemoteFXNetworkCount(ctx *types.ScrapeContext, ch cha
|
|||||||
c.BaseTCPRTT,
|
c.BaseTCPRTT,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
utils.MilliSecToSec(d.BaseTCPRTT),
|
utils.MilliSecToSec(d.BaseTCPRTT),
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.BaseUDPRTT,
|
c.BaseUDPRTT,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
utils.MilliSecToSec(d.BaseUDPRTT),
|
utils.MilliSecToSec(d.BaseUDPRTT),
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CurrentTCPBandwidth,
|
c.CurrentTCPBandwidth,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
(d.CurrentTCPBandwidth*1000)/8,
|
(d.CurrentTCPBandwidth*1000)/8,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CurrentTCPRTT,
|
c.CurrentTCPRTT,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
utils.MilliSecToSec(d.CurrentTCPRTT),
|
utils.MilliSecToSec(d.CurrentTCPRTT),
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CurrentUDPBandwidth,
|
c.CurrentUDPBandwidth,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
(d.CurrentUDPBandwidth*1000)/8,
|
(d.CurrentUDPBandwidth*1000)/8,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.CurrentUDPRTT,
|
c.CurrentUDPRTT,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
utils.MilliSecToSec(d.CurrentUDPRTT),
|
utils.MilliSecToSec(d.CurrentUDPRTT),
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.TotalReceivedBytes,
|
c.TotalReceivedBytes,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.TotalReceivedBytes,
|
d.TotalReceivedBytes,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.TotalSentBytes,
|
c.TotalSentBytes,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.TotalSentBytes,
|
d.TotalSentBytes,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.UDPPacketsReceivedPersec,
|
c.UDPPacketsReceivedPersec,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.UDPPacketsReceivedPersec,
|
d.UDPPacketsReceivedPersec,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.UDPPacketsSentPersec,
|
c.UDPPacketsSentPersec,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.UDPPacketsSentPersec,
|
d.UDPPacketsSentPersec,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
|
)
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.FECRate,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
d.FECRate,
|
||||||
|
normalizeSessionName(d.Name),
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.LossRate,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
d.LossRate,
|
||||||
|
normalizeSessionName(d.Name),
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.RetransmissionRate,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
d.RetransmissionRate,
|
||||||
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type perflibRemoteFxGraphics struct {
|
type perflibRemoteFxGraphics struct {
|
||||||
@@ -299,16 +343,16 @@ type perflibRemoteFxGraphics struct {
|
|||||||
SourceFramesPerSecond float64 `perflib:"Source Frames/Second"`
|
SourceFramesPerSecond float64 `perflib:"Source Frames/Second"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectRemoteFXGraphicsCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectRemoteFXGraphicsCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
dst := make([]perflibRemoteFxGraphics, 0)
|
dst := make([]perflibRemoteFxGraphics, 0)
|
||||||
err := perflib.UnmarshalObject(ctx.PerfObjects["RemoteFX Graphics"], &dst, c.logger)
|
err := perflib.UnmarshalObject(ctx.PerfObjects["RemoteFX Graphics"], &dst, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range dst {
|
for _, d := range dst {
|
||||||
// only connect metrics for remote named sessions
|
// only connect metrics for remote named sessions
|
||||||
n := strings.ToLower(d.Name)
|
n := strings.ToLower(normalizeSessionName(d.Name))
|
||||||
if n == "" || n == "services" || n == "console" {
|
if n == "" || n == "services" || n == "console" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -316,60 +360,65 @@ func (c *collector) collectRemoteFXGraphicsCounters(ctx *types.ScrapeContext, ch
|
|||||||
c.AverageEncodingTime,
|
c.AverageEncodingTime,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
utils.MilliSecToSec(d.AverageEncodingTime),
|
utils.MilliSecToSec(d.AverageEncodingTime),
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.FrameQuality,
|
c.FrameQuality,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
d.FrameQuality,
|
d.FrameQuality,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.FramesSkippedPerSecondInsufficientResources,
|
c.FramesSkippedPerSecondInsufficientResources,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.FramesSkippedPerSecondInsufficientClientResources,
|
d.FramesSkippedPerSecondInsufficientClientResources,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
"client",
|
"client",
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.FramesSkippedPerSecondInsufficientResources,
|
c.FramesSkippedPerSecondInsufficientResources,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.FramesSkippedPerSecondInsufficientNetworkResources,
|
d.FramesSkippedPerSecondInsufficientNetworkResources,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
"network",
|
"network",
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.FramesSkippedPerSecondInsufficientResources,
|
c.FramesSkippedPerSecondInsufficientResources,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.FramesSkippedPerSecondInsufficientServerResources,
|
d.FramesSkippedPerSecondInsufficientServerResources,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
"server",
|
"server",
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.GraphicsCompressionratio,
|
c.GraphicsCompressionratio,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
d.GraphicsCompressionratio,
|
d.GraphicsCompressionratio,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.InputFramesPerSecond,
|
c.InputFramesPerSecond,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.InputFramesPerSecond,
|
d.InputFramesPerSecond,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.OutputFramesPerSecond,
|
c.OutputFramesPerSecond,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.OutputFramesPerSecond,
|
d.OutputFramesPerSecond,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.SourceFramesPerSecond,
|
c.SourceFramesPerSecond,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.SourceFramesPerSecond,
|
d.SourceFramesPerSecond,
|
||||||
d.Name,
|
normalizeSessionName(d.Name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalizeSessionName ensure that the session is the same between WTS API and performance counters
|
||||||
|
func normalizeSessionName(sessionName string) string {
|
||||||
|
return strings.Replace(sessionName, "RDP-tcp", "RDP-Tcp", 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,19 @@
|
|||||||
package scheduled_task
|
package scheduled_task
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
"github.com/go-kit/log/level"
|
"github.com/go-kit/log/level"
|
||||||
"github.com/go-ole/go-ole"
|
"github.com/go-ole/go-ole"
|
||||||
"github.com/go-ole/go-ole/oleutil"
|
"github.com/go-ole/go-ole/oleutil"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -63,7 +65,6 @@ const (
|
|||||||
TASK_RESULT_SUCCESS TaskResult = 0x0
|
TASK_RESULT_SUCCESS TaskResult = 0x0
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisteredTask ...
|
|
||||||
type ScheduledTask struct {
|
type ScheduledTask struct {
|
||||||
Name string
|
Name string
|
||||||
Path string
|
Path string
|
||||||
@@ -117,18 +118,6 @@ func (c *collector) GetPerfCounter() ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) Build() error {
|
func (c *collector) Build() error {
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
|
|
||||||
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
|
|
||||||
if err != nil {
|
|
||||||
code := err.(*ole.OleError).Code()
|
|
||||||
if code != ole.S_OK && code != S_FALSE {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
defer ole.CoUninitialize()
|
|
||||||
|
|
||||||
c.LastResult = prometheus.NewDesc(
|
c.LastResult = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "last_result"),
|
prometheus.BuildFQName(types.Namespace, Name, "last_result"),
|
||||||
"The result that was returned the last time the registered task was run",
|
"The result that was returned the last time the registered task was run",
|
||||||
@@ -150,6 +139,8 @@ func (c *collector) Build() error {
|
|||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
c.taskIncludePattern, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", *c.taskInclude))
|
c.taskIncludePattern, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", *c.taskInclude))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -164,8 +155,8 @@ func (c *collector) Build() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting user metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting user metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,10 +165,10 @@ func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
|
|
||||||
var TASK_STATES = []string{"disabled", "queued", "ready", "running", "unknown"}
|
var TASK_STATES = []string{"disabled", "queued", "ready", "running", "unknown"}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
scheduledTasks, err := getScheduledTasks()
|
scheduledTasks, err := getScheduledTasks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, task := range scheduledTasks {
|
for _, task := range scheduledTasks {
|
||||||
@@ -222,7 +213,7 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const SCHEDULED_TASK_PROGRAM_ID = "Schedule.Service.1"
|
const SCHEDULED_TASK_PROGRAM_ID = "Schedule.Service.1"
|
||||||
@@ -231,6 +222,21 @@ const SCHEDULED_TASK_PROGRAM_ID = "Schedule.Service.1"
|
|||||||
const S_FALSE = 0x00000001
|
const S_FALSE = 0x00000001
|
||||||
|
|
||||||
func getScheduledTasks() (scheduledTasks ScheduledTasks, err error) {
|
func getScheduledTasks() (scheduledTasks ScheduledTasks, err error) {
|
||||||
|
// The only way to run WMI queries in parallel while being thread-safe is to
|
||||||
|
// ensure the CoInitialize[Ex]() call is bound to its current OS thread.
|
||||||
|
// Otherwise, attempting to initialize and run parallel queries across
|
||||||
|
// goroutines will result in protected memory errors.
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil {
|
||||||
|
var oleCode *ole.OleError
|
||||||
|
if errors.As(err, &oleCode) && oleCode.Code() != ole.S_OK && oleCode.Code() != S_FALSE {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defer ole.CoUninitialize()
|
||||||
|
|
||||||
schedClassID, err := ole.ClassIDFrom(SCHEDULED_TASK_PROGRAM_ID)
|
schedClassID, err := ole.ClassIDFrom(SCHEDULED_TASK_PROGRAM_ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return scheduledTasks, err
|
return scheduledTasks, err
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
@@ -23,16 +25,19 @@ const (
|
|||||||
Name = "service"
|
Name = "service"
|
||||||
FlagServiceWhereClause = "collector.service.services-where"
|
FlagServiceWhereClause = "collector.service.services-where"
|
||||||
FlagServiceUseAPI = "collector.service.use-api"
|
FlagServiceUseAPI = "collector.service.use-api"
|
||||||
|
FlagServiceCollectorV2 = "collector.service.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ServiceWhereClause string `yaml:"service_where_clause"`
|
ServiceWhereClause string `yaml:"service_where_clause"`
|
||||||
UseAPI bool `yaml:"use_api"`
|
UseAPI bool `yaml:"use_api"`
|
||||||
|
V2 bool `yaml:"v2"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var ConfigDefaults = Config{
|
var ConfigDefaults = Config{
|
||||||
ServiceWhereClause: "",
|
ServiceWhereClause: "",
|
||||||
UseAPI: false,
|
UseAPI: false,
|
||||||
|
V2: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// A collector is a Prometheus collector for WMI Win32_Service metrics
|
// A collector is a Prometheus collector for WMI Win32_Service metrics
|
||||||
@@ -41,13 +46,13 @@ type collector struct {
|
|||||||
|
|
||||||
serviceWhereClause *string
|
serviceWhereClause *string
|
||||||
useAPI *bool
|
useAPI *bool
|
||||||
|
v2 *bool
|
||||||
|
|
||||||
Information *prometheus.Desc
|
Information *prometheus.Desc
|
||||||
State *prometheus.Desc
|
State *prometheus.Desc
|
||||||
StartMode *prometheus.Desc
|
StartMode *prometheus.Desc
|
||||||
Status *prometheus.Desc
|
Status *prometheus.Desc
|
||||||
|
StateV2 *prometheus.Desc
|
||||||
queryWhereClause string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(logger log.Logger, config *Config) types.Collector {
|
func New(logger log.Logger, config *Config) types.Collector {
|
||||||
@@ -73,6 +78,10 @@ func NewWithFlags(app *kingpin.Application) types.Collector {
|
|||||||
FlagServiceUseAPI,
|
FlagServiceUseAPI,
|
||||||
"Use API calls to collect service data instead of WMI. Flag 'collector.service.services-where' won't be effective.",
|
"Use API calls to collect service data instead of WMI. Flag 'collector.service.services-where' won't be effective.",
|
||||||
).Default(strconv.FormatBool(ConfigDefaults.UseAPI)).Bool(),
|
).Default(strconv.FormatBool(ConfigDefaults.UseAPI)).Bool(),
|
||||||
|
v2: app.Flag(
|
||||||
|
FlagServiceCollectorV2,
|
||||||
|
"Enable V2 service collector. This collector can services state much more efficiently, can't provide general service information.",
|
||||||
|
).Default(strconv.FormatBool(ConfigDefaults.V2)).Bool(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,25 +129,37 @@ func (c *collector) Build() error {
|
|||||||
[]string{"name", "status"},
|
[]string{"name", "status"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.queryWhereClause = *c.serviceWhereClause
|
c.StateV2 = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "state"),
|
||||||
|
"The state of the service (State)",
|
||||||
|
[]string{"name", "display_name", "status"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if *c.useAPI {
|
var err error
|
||||||
if err := c.collectAPI(ch); err != nil {
|
|
||||||
|
switch {
|
||||||
|
case *c.useAPI:
|
||||||
|
if err = c.collectAPI(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting API service metrics:", "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting API service metrics:", "err", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
} else {
|
case *c.v2:
|
||||||
if err := c.collectWMI(ch); err != nil {
|
if err = c.collectAPIV2(ch); err != nil {
|
||||||
|
_ = level.Error(c.logger).Log("msg", "failed collecting API service metrics:", "err", err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if err = c.collectWMI(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", "failed collecting WMI service metrics:", "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting WMI service metrics:", "err", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Win32_Service docs:
|
// Win32_Service docs:
|
||||||
@@ -164,7 +185,7 @@ var (
|
|||||||
"paused",
|
"paused",
|
||||||
"unknown",
|
"unknown",
|
||||||
}
|
}
|
||||||
apiStateValues = map[uint]string{
|
apiStateValues = map[uint32]string{
|
||||||
windows.SERVICE_CONTINUE_PENDING: "continue pending",
|
windows.SERVICE_CONTINUE_PENDING: "continue pending",
|
||||||
windows.SERVICE_PAUSE_PENDING: "pause pending",
|
windows.SERVICE_PAUSE_PENDING: "pause pending",
|
||||||
windows.SERVICE_PAUSED: "paused",
|
windows.SERVICE_PAUSED: "paused",
|
||||||
@@ -205,12 +226,12 @@ var (
|
|||||||
|
|
||||||
func (c *collector) collectWMI(ch chan<- prometheus.Metric) error {
|
func (c *collector) collectWMI(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_Service
|
var dst []Win32_Service
|
||||||
q := wmi.QueryAllWhere(&dst, c.queryWhereClause, c.logger)
|
q := wmi.QueryAllWhere(&dst, *c.serviceWhereClause, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, service := range dst {
|
for _, service := range dst {
|
||||||
pid := fmt.Sprintf("%d", uint64(service.ProcessId))
|
pid := strconv.FormatUint(uint64(service.ProcessId), 10)
|
||||||
|
|
||||||
runAs := ""
|
runAs := ""
|
||||||
if service.StartName != nil {
|
if service.StartName != nil {
|
||||||
@@ -319,7 +340,7 @@ func (c *collector) collectAPI(ch chan<- prometheus.Metric) error {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pid := fmt.Sprintf("%d", uint64(serviceStatus.ProcessId))
|
pid := strconv.FormatUint(uint64(serviceStatus.ProcessId), 10)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.Information,
|
c.Information,
|
||||||
@@ -333,7 +354,7 @@ func (c *collector) collectAPI(ch chan<- prometheus.Metric) error {
|
|||||||
|
|
||||||
for _, state := range apiStateValues {
|
for _, state := range apiStateValues {
|
||||||
isCurrentState := 0.0
|
isCurrentState := 0.0
|
||||||
if state == apiStateValues[uint(serviceStatus.State)] {
|
if state == apiStateValues[uint32(serviceStatus.State)] {
|
||||||
isCurrentState = 1.0
|
isCurrentState = 1.0
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -362,3 +383,92 @@ func (c *collector) collectAPI(ch chan<- prometheus.Metric) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *collector) collectAPIV2(ch chan<- prometheus.Metric) error {
|
||||||
|
services, err := c.queryAllServiceStates()
|
||||||
|
if err != nil {
|
||||||
|
_ = level.Warn(c.logger).Log("msg", "Failed to query services", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if services == nil {
|
||||||
|
_ = level.Warn(c.logger).Log("msg", "No services queried")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var isCurrentState float64
|
||||||
|
|
||||||
|
for _, svc := range services {
|
||||||
|
for state, stateValue := range apiStateValues {
|
||||||
|
isCurrentState = 0.0
|
||||||
|
if state == svc.ServiceStatusProcess.CurrentState {
|
||||||
|
isCurrentState = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.StateV2,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
isCurrentState,
|
||||||
|
windows.UTF16PtrToString(svc.ServiceName),
|
||||||
|
windows.UTF16PtrToString(svc.DisplayName),
|
||||||
|
stateValue,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// queryAllServiceStates returns all service states of the current Windows system
|
||||||
|
// This is realized by ask Service Manager directly.
|
||||||
|
//
|
||||||
|
// Unless explicitly stated otherwise all files in this repository are licensed
|
||||||
|
// under the Apache License Version 2.0.
|
||||||
|
// This product includes software developed at Datadog (https://www.datadoghq.com/).
|
||||||
|
// Copyright 2016-present Datadog, Inc.
|
||||||
|
//
|
||||||
|
// Source: https://github.com/DataDog/datadog-agent/blob/afbd8b6c87939c92610c654cb07fdfd439e4fb27/pkg/util/winutil/scmmonitor.go#L61-L96
|
||||||
|
func (c *collector) queryAllServiceStates() ([]windows.ENUM_SERVICE_STATUS_PROCESS, error) {
|
||||||
|
// EnumServiceStatusEx requires only SC_MANAGER_ENUM_SERVICE.
|
||||||
|
h, err := windows.OpenSCManager(nil, nil, windows.SC_MANAGER_ENUMERATE_SERVICE)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to open scm: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := &mgr.Mgr{Handle: h}
|
||||||
|
defer func() {
|
||||||
|
if err := m.Disconnect(); err != nil {
|
||||||
|
_ = level.Warn(c.logger).Log("msg", "Failed to disconnect from scm", "err", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var bytesNeeded, servicesReturned uint32
|
||||||
|
var buf []byte
|
||||||
|
for {
|
||||||
|
var p *byte
|
||||||
|
if len(buf) > 0 {
|
||||||
|
p = &buf[0]
|
||||||
|
}
|
||||||
|
err = windows.EnumServicesStatusEx(m.Handle, windows.SC_ENUM_PROCESS_INFO,
|
||||||
|
windows.SERVICE_WIN32, windows.SERVICE_STATE_ALL,
|
||||||
|
p, uint32(len(buf)), &bytesNeeded, &servicesReturned, nil, nil)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !errors.Is(err, windows.ERROR_MORE_DATA) {
|
||||||
|
return nil, fmt.Errorf("failed to enum services %w", err)
|
||||||
|
}
|
||||||
|
if bytesNeeded <= uint32(len(buf)) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
buf = make([]byte, bytesNeeded)
|
||||||
|
}
|
||||||
|
|
||||||
|
if servicesReturned == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
services := unsafe.Slice((*windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0])), servicesReturned)
|
||||||
|
|
||||||
|
return services, nil
|
||||||
|
}
|
||||||
|
|||||||
447
pkg/collector/smbclient/smbclient.go
Normal file
447
pkg/collector/smbclient/smbclient.go
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package smbclient
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"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/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Name = "smbclient"
|
||||||
|
FlagSmbClientListAllCollectors = "collectors.smbclient.list"
|
||||||
|
FlagSmbClientCollectorsEnabled = "collectors.smbclient.enabled"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
CollectorsEnabled string `yaml:"collectors_enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var ConfigDefaults = Config{
|
||||||
|
CollectorsEnabled: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
type collector struct {
|
||||||
|
logger log.Logger
|
||||||
|
|
||||||
|
smbclientListAllCollectors *bool
|
||||||
|
smbclientCollectorsEnabled *string
|
||||||
|
|
||||||
|
ReadRequestQueueSecsTotal *prometheus.Desc
|
||||||
|
ReadBytesTotal *prometheus.Desc
|
||||||
|
ReadsTotal *prometheus.Desc
|
||||||
|
ReadBytesTransmittedViaSMBDirectTotal *prometheus.Desc
|
||||||
|
ReadRequestsTransmittedViaSMBDirectTotal *prometheus.Desc
|
||||||
|
TurboIOReadsTotal *prometheus.Desc
|
||||||
|
ReadSecsTotal *prometheus.Desc
|
||||||
|
|
||||||
|
WriteRequestQueueSecsTotal *prometheus.Desc
|
||||||
|
WriteBytesTotal *prometheus.Desc
|
||||||
|
WritesTotal *prometheus.Desc
|
||||||
|
WriteBytesTransmittedViaSMBDirectTotal *prometheus.Desc
|
||||||
|
WriteRequestsTransmittedViaSMBDirectTotal *prometheus.Desc
|
||||||
|
TurboIOWritesTotal *prometheus.Desc
|
||||||
|
WriteSecsTotal *prometheus.Desc
|
||||||
|
|
||||||
|
RequestQueueSecsTotal *prometheus.Desc
|
||||||
|
RequestSecs *prometheus.Desc
|
||||||
|
CreditStallsTotal *prometheus.Desc
|
||||||
|
CurrentDataQueued *prometheus.Desc
|
||||||
|
DataBytesTotal *prometheus.Desc
|
||||||
|
DataRequestsTotal *prometheus.Desc
|
||||||
|
MetadataRequestsTotal *prometheus.Desc
|
||||||
|
|
||||||
|
enabledCollectors []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// All available collector functions
|
||||||
|
var smbclientAllCollectorNames = []string{
|
||||||
|
"ClientShares",
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(logger log.Logger, config *Config) types.Collector {
|
||||||
|
if config == nil {
|
||||||
|
config = &ConfigDefaults
|
||||||
|
}
|
||||||
|
|
||||||
|
smbclientListAllCollectors := false
|
||||||
|
c := &collector{
|
||||||
|
smbclientCollectorsEnabled: &config.CollectorsEnabled,
|
||||||
|
smbclientListAllCollectors: &smbclientListAllCollectors,
|
||||||
|
}
|
||||||
|
c.SetLogger(logger)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithFlags(app *kingpin.Application) types.Collector {
|
||||||
|
return &collector{
|
||||||
|
smbclientListAllCollectors: app.Flag(
|
||||||
|
FlagSmbClientListAllCollectors,
|
||||||
|
"List the collectors along with their perflib object name/ids",
|
||||||
|
).Bool(),
|
||||||
|
|
||||||
|
smbclientCollectorsEnabled: app.Flag(
|
||||||
|
FlagSmbClientCollectorsEnabled,
|
||||||
|
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||||
|
).Default(ConfigDefaults.CollectorsEnabled).String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return []string{
|
||||||
|
"SMB Client Shares",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) Build() error {
|
||||||
|
// desc creates a new prometheus description
|
||||||
|
desc := func(metricName string, description string, labels []string) *prometheus.Desc {
|
||||||
|
return prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, "smbclient", metricName),
|
||||||
|
description,
|
||||||
|
labels,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.RequestQueueSecsTotal = desc("data_queue_seconds_total",
|
||||||
|
"Seconds requests waited on queue on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.ReadRequestQueueSecsTotal = desc("read_queue_seconds_total",
|
||||||
|
"Seconds read requests waited on queue on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.WriteRequestQueueSecsTotal = desc("write_queue_seconds_total",
|
||||||
|
"Seconds write requests waited on queue on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.RequestSecs = desc("request_seconds_total",
|
||||||
|
"Seconds waiting for requests on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.CreditStallsTotal = desc("stalls_total",
|
||||||
|
"The number of requests delayed based on insufficient credits on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.CurrentDataQueued = desc("requests_queued",
|
||||||
|
"The point in time number of requests outstanding on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.DataBytesTotal = desc("data_bytes_total",
|
||||||
|
"The bytes read or written on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.DataRequestsTotal = desc("requests_total",
|
||||||
|
"The requests on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.MetadataRequestsTotal = desc("metadata_requests_total",
|
||||||
|
"The metadata requests on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.ReadBytesTransmittedViaSMBDirectTotal = desc("read_bytes_via_smbdirect_total",
|
||||||
|
"The bytes read from this share via RDMA direct placement",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.ReadBytesTotal = desc("read_bytes_total",
|
||||||
|
"The bytes read on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.ReadRequestsTransmittedViaSMBDirectTotal = desc("read_requests_via_smbdirect_total",
|
||||||
|
"The read requests on this share via RDMA direct placement",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.ReadsTotal = desc("read_requests_total",
|
||||||
|
"The read requests on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.TurboIOReadsTotal = desc("turbo_io_reads_total",
|
||||||
|
"The read requests that go through Turbo I/O",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.TurboIOWritesTotal = desc("turbo_io_writes_total",
|
||||||
|
"The write requests that go through Turbo I/O",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.WriteBytesTransmittedViaSMBDirectTotal = desc("write_bytes_via_smbdirect_total",
|
||||||
|
"The written bytes to this share via RDMA direct placement",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.WriteBytesTotal = desc("write_bytes_total",
|
||||||
|
"The bytes written on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.WriteRequestsTransmittedViaSMBDirectTotal = desc("write_requests_via_smbdirect_total",
|
||||||
|
"The write requests to this share via RDMA direct placement",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.WritesTotal = desc("write_requests_total",
|
||||||
|
"The write requests on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.ReadSecsTotal = desc("read_seconds_total",
|
||||||
|
"Seconds waiting for read requests on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
c.WriteSecsTotal = desc("write_seconds_total",
|
||||||
|
"Seconds waiting for write requests on this share",
|
||||||
|
[]string{"server", "share"},
|
||||||
|
)
|
||||||
|
|
||||||
|
c.enabledCollectors = make([]string, 0, len(smbclientAllCollectorNames))
|
||||||
|
|
||||||
|
collectorDesc := map[string]string{
|
||||||
|
"ClientShares": "SMB Client Shares",
|
||||||
|
}
|
||||||
|
|
||||||
|
if *c.smbclientListAllCollectors {
|
||||||
|
fmt.Printf("%-32s %-32s\n", "Collector Name", "Perflib Object")
|
||||||
|
for _, cname := range smbclientAllCollectorNames {
|
||||||
|
fmt.Printf("%-32s %-32s\n", cname, collectorDesc[cname])
|
||||||
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *c.smbclientCollectorsEnabled == "" {
|
||||||
|
for _, collectorName := range smbclientAllCollectorNames {
|
||||||
|
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, collectorName := range strings.Split(*c.smbclientCollectorsEnabled, ",") {
|
||||||
|
if slices.Contains(smbclientAllCollectorNames, collectorName) {
|
||||||
|
c.enabledCollectors = append(c.enabledCollectors, collectorName)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unknown smbclient collector: %s", collectorName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect collects smb client metrics and sends them to prometheus
|
||||||
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
|
collectorFuncs := map[string]func(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error{
|
||||||
|
"ClientShares": c.collectClientShares,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, collectorName := range c.enabledCollectors {
|
||||||
|
if err := collectorFuncs[collectorName](ctx, ch); err != nil {
|
||||||
|
_ = level.Error(c.logger).Log("msg", "Error in "+collectorName, "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perflib: SMB Client Shares
|
||||||
|
type perflibClientShares struct {
|
||||||
|
Name string
|
||||||
|
|
||||||
|
AvgDataQueueLength float64 `perflib:"Avg. Data Queue Length"`
|
||||||
|
AvgReadQueueLength float64 `perflib:"Avg. Read Queue Length"`
|
||||||
|
AvgSecPerRead float64 `perflib:"Avg. sec/Read"`
|
||||||
|
AvgSecPerWrite float64 `perflib:"Avg. sec/Write"`
|
||||||
|
AvgSecPerDataRequest float64 `perflib:"Avg. sec/Data Request"`
|
||||||
|
AvgWriteQueueLength float64 `perflib:"Avg. Write Queue Length"`
|
||||||
|
CreditStallsPerSec float64 `perflib:"Credit Stalls/sec"`
|
||||||
|
CurrentDataQueueLength float64 `perflib:"Current Data Queue Length"`
|
||||||
|
DataBytesPerSec float64 `perflib:"Data Bytes/sec"`
|
||||||
|
DataRequestsPerSec float64 `perflib:"Data Requests/sec"`
|
||||||
|
MetadataRequestsPerSec float64 `perflib:"Metadata Requests/sec"`
|
||||||
|
ReadBytesTransmittedViaSMBDirectPerSec float64 `perflib:"Read Bytes transmitted via SMB Direct/sec"`
|
||||||
|
ReadBytesPerSec float64 `perflib:"Read Bytes/sec"`
|
||||||
|
ReadRequestsTransmittedViaSMBDirectPerSec float64 `perflib:"Read Requests transmitted via SMB Direct/sec"`
|
||||||
|
ReadRequestsPerSec float64 `perflib:"Read Requests/sec"`
|
||||||
|
TurboIOReadsPerSec float64 `perflib:"Turbo I/O Reads/sec"`
|
||||||
|
TurboIOWritesPerSec float64 `perflib:"Turbo I/O Writes/sec"`
|
||||||
|
WriteBytesTransmittedViaSMBDirectPerSec float64 `perflib:"Write Bytes transmitted via SMB Direct/sec"`
|
||||||
|
WriteBytesPerSec float64 `perflib:"Write Bytes/sec"`
|
||||||
|
WriteRequestsTransmittedViaSMBDirectPerSec float64 `perflib:"Write Requests transmitted via SMB Direct/sec"`
|
||||||
|
WriteRequestsPerSec float64 `perflib:"Write Requests/sec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) collectClientShares(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
|
var data []perflibClientShares
|
||||||
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["SMB Client Shares"], &data, c.logger); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, instance := range data {
|
||||||
|
if instance.Name == "_Total" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed := strings.FieldsFunc(instance.Name, func(r rune) bool { return r == '\\' })
|
||||||
|
serverValue := parsed[0]
|
||||||
|
shareValue := parsed[1]
|
||||||
|
// Request time spent on queue. Convert from ticks to seconds.
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.RequestQueueSecsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.AvgDataQueueLength*perflib.TicksToSecondScaleFactor,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Read time spent on queue. Convert from ticks to seconds.
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.ReadRequestQueueSecsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.AvgReadQueueLength*perflib.TicksToSecondScaleFactor,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.ReadSecsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.AvgSecPerRead*perflib.TicksToSecondScaleFactor,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.WriteSecsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.AvgSecPerWrite*perflib.TicksToSecondScaleFactor,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.RequestSecs,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.AvgSecPerDataRequest*perflib.TicksToSecondScaleFactor,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Write time spent on queue. Convert from ticks to seconds.
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.WriteRequestQueueSecsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.AvgWriteQueueLength*perflib.TicksToSecondScaleFactor,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.CreditStallsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.CreditStallsPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.CurrentDataQueued,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
instance.CurrentDataQueueLength,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.DataBytesTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.DataBytesPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.DataRequestsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.DataRequestsPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.MetadataRequestsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.MetadataRequestsPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.ReadBytesTransmittedViaSMBDirectTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.ReadBytesTransmittedViaSMBDirectPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.ReadBytesTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.ReadBytesPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.ReadRequestsTransmittedViaSMBDirectTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.ReadRequestsTransmittedViaSMBDirectPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.ReadsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.ReadRequestsPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.TurboIOReadsTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.TurboIOReadsPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.TurboIOWritesTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.TurboIOWritesPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.WriteBytesTransmittedViaSMBDirectTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.WriteBytesTransmittedViaSMBDirectPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.WriteBytesTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.WriteBytesPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.WriteRequestsTransmittedViaSMBDirectTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.WriteRequestsTransmittedViaSMBDirectPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.WritesTotal,
|
||||||
|
prometheus.CounterValue,
|
||||||
|
instance.WriteRequestsPerSec,
|
||||||
|
serverValue, shareValue,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
12
pkg/collector/smbclient/smbclient_test.go
Normal file
12
pkg/collector/smbclient/smbclient_test.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package smbclient_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/collector/smbclient"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/testutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkCollector(b *testing.B) {
|
||||||
|
testutils.FuncBenchmarkCollector(b, smbclient.Name, smbclient.NewWithFlags)
|
||||||
|
}
|
||||||
@@ -399,8 +399,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting smtp metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting smtp metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -454,10 +454,10 @@ type PerflibSMTPServer struct {
|
|||||||
RoutingTableLookupsTotal float64 `perflib:"Routing Table Lookups Total"`
|
RoutingTableLookupsTotal float64 `perflib:"Routing Table Lookups Total"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []PerflibSMTPServer
|
var dst []PerflibSMTPServer
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["SMTP Server"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["SMTP Server"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, server := range dst {
|
for _, server := range dst {
|
||||||
@@ -755,5 +755,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting system metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting system metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -112,10 +112,10 @@ type system struct {
|
|||||||
Threads float64 `perflib:"Threads"`
|
Threads float64 `perflib:"Threads"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []system
|
var dst []system
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["System"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["System"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -148,5 +148,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
dst[0].Threads,
|
dst[0].Threads,
|
||||||
)
|
)
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting tcp metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting tcp metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -194,12 +194,12 @@ func writeTCPCounters(metrics tcp, labels []string, c *collector, ch chan<- prom
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []tcp
|
var dst []tcp
|
||||||
|
|
||||||
// TCPv4 counters
|
// TCPv4 counters
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["TCPv4"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["TCPv4"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) != 0 {
|
if len(dst) != 0 {
|
||||||
writeTCPCounters(dst[0], []string{"ipv4"}, c, ch)
|
writeTCPCounters(dst[0], []string{"ipv4"}, c, ch)
|
||||||
@@ -207,11 +207,11 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
|
|
||||||
// TCPv6 counters
|
// TCPv6 counters
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["TCPv6"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["TCPv6"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) != 0 {
|
if len(dst) != 0 {
|
||||||
writeTCPCounters(dst[0], []string{"ipv6"}, c, ch)
|
writeTCPCounters(dst[0], []string{"ipv6"}, c, ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,24 +326,24 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectAudio(ch); err != nil {
|
if err := c.collectAudio(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting teradici session audio metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting teradici session audio metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectGeneral(ch); err != nil {
|
if err := c.collectGeneral(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting teradici session general metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting teradici session general metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectImaging(ch); err != nil {
|
if err := c.collectImaging(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting teradici session imaging metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting teradici session imaging metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectNetwork(ch); err != nil {
|
if err := c.collectNetwork(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting teradici session network metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting teradici session network metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectUsb(ch); err != nil {
|
if err := c.collectUsb(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting teradici session USB metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting teradici session USB metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -401,14 +401,14 @@ type win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics struct {
|
|||||||
USBTXBWkbitPersec uint64
|
USBTXBWkbitPersec uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectAudio(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectAudio(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics
|
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -441,17 +441,17 @@ func (c *collector) collectAudio(ch chan<- prometheus.Metric) (*prometheus.Desc,
|
|||||||
float64(dst[0].AudioTXBWLimitkbitPersec),
|
float64(dst[0].AudioTXBWLimitkbitPersec),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectGeneral(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectGeneral(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics
|
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -496,17 +496,17 @@ func (c *collector) collectGeneral(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
float64(dst[0].TXPacketsLost),
|
float64(dst[0].TXPacketsLost),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectImaging(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectImaging(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics
|
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -575,17 +575,17 @@ func (c *collector) collectImaging(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
float64(dst[0].ImagingTXBWkbitPersec),
|
float64(dst[0].ImagingTXBWkbitPersec),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectNetwork(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectNetwork(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
|
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -648,17 +648,17 @@ func (c *collector) collectNetwork(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
float64(dst[0].TXPacketLossPercent_Base),
|
float64(dst[0].TXPacketLossPercent_Base),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectUsb(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectUsb(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics
|
var dst []win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -685,5 +685,5 @@ func (c *collector) collectUsb(ch chan<- prometheus.Metric) (*prometheus.Desc, e
|
|||||||
float64(dst[0].USBTXBWkbitPersec),
|
float64(dst[0].USBTXBWkbitPersec),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ package terminal_services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
"github.com/go-kit/log"
|
||||||
"github.com/go-kit/log/level"
|
"github.com/go-kit/log/level"
|
||||||
|
"github.com/prometheus-community/windows_exporter/pkg/headers/wtsapi32"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||||
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
"github.com/prometheus-community/windows_exporter/pkg/wmi"
|
||||||
@@ -52,15 +55,16 @@ type collector struct {
|
|||||||
|
|
||||||
connectionBrokerEnabled bool
|
connectionBrokerEnabled bool
|
||||||
|
|
||||||
|
hServer syscall.Handle
|
||||||
|
|
||||||
|
SessionInfo *prometheus.Desc
|
||||||
LocalSessionCount *prometheus.Desc
|
LocalSessionCount *prometheus.Desc
|
||||||
ConnectionBrokerPerformance *prometheus.Desc
|
ConnectionBrokerPerformance *prometheus.Desc
|
||||||
HandleCount *prometheus.Desc
|
HandleCount *prometheus.Desc
|
||||||
PageFaultsPersec *prometheus.Desc
|
PageFaultsPersec *prometheus.Desc
|
||||||
PageFileBytes *prometheus.Desc
|
PageFileBytes *prometheus.Desc
|
||||||
PageFileBytesPeak *prometheus.Desc
|
PageFileBytesPeak *prometheus.Desc
|
||||||
PercentPrivilegedTime *prometheus.Desc
|
PercentCPUTime *prometheus.Desc
|
||||||
PercentProcessorTime *prometheus.Desc
|
|
||||||
PercentUserTime *prometheus.Desc
|
|
||||||
PoolNonpagedBytes *prometheus.Desc
|
PoolNonpagedBytes *prometheus.Desc
|
||||||
PoolPagedBytes *prometheus.Desc
|
PoolPagedBytes *prometheus.Desc
|
||||||
PrivateBytes *prometheus.Desc
|
PrivateBytes *prometheus.Desc
|
||||||
@@ -91,7 +95,6 @@ func (c *collector) SetLogger(logger log.Logger) {
|
|||||||
|
|
||||||
func (c *collector) GetPerfCounter() ([]string, error) {
|
func (c *collector) GetPerfCounter() ([]string, error) {
|
||||||
return []string{
|
return []string{
|
||||||
"Terminal Services",
|
|
||||||
"Terminal Services Session",
|
"Terminal Services Session",
|
||||||
"Remote Desktop Connection Broker Counterset",
|
"Remote Desktop Connection Broker Counterset",
|
||||||
}, nil
|
}, nil
|
||||||
@@ -100,10 +103,10 @@ func (c *collector) GetPerfCounter() ([]string, error) {
|
|||||||
func (c *collector) Build() error {
|
func (c *collector) Build() error {
|
||||||
c.connectionBrokerEnabled = isConnectionBrokerServer(c.logger)
|
c.connectionBrokerEnabled = isConnectionBrokerServer(c.logger)
|
||||||
|
|
||||||
c.LocalSessionCount = prometheus.NewDesc(
|
c.SessionInfo = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "local_session_count"),
|
prometheus.BuildFQName(types.Namespace, Name, "session_info"),
|
||||||
"Number of Terminal Services sessions",
|
"Terminal Services sessions info",
|
||||||
[]string{"session"},
|
[]string{"session_name", "user", "host", "state"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.ConnectionBrokerPerformance = prometheus.NewDesc(
|
c.ConnectionBrokerPerformance = prometheus.NewDesc(
|
||||||
@@ -136,22 +139,10 @@ func (c *collector) Build() error {
|
|||||||
[]string{"session_name"},
|
[]string{"session_name"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.PercentPrivilegedTime = prometheus.NewDesc(
|
c.PercentCPUTime = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "privileged_time_seconds_total"),
|
prometheus.BuildFQName(types.Namespace, Name, "cpu_time_seconds_total"),
|
||||||
"Total elapsed time that the threads of the process have spent executing code in privileged mode.",
|
"Total elapsed time that this process's threads have spent executing code.",
|
||||||
[]string{"session_name"},
|
[]string{"mode", "session_name"},
|
||||||
nil,
|
|
||||||
)
|
|
||||||
c.PercentProcessorTime = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "processor_time_seconds_total"),
|
|
||||||
"Total elapsed time that all of the threads of this process used the processor to execute instructions.",
|
|
||||||
[]string{"session_name"},
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
c.PercentUserTime = prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "user_time_seconds_total"),
|
|
||||||
"Total elapsed time that this process's threads have spent executing code in user mode. Applications, environment Names, and integral Names execute in user mode.",
|
|
||||||
[]string{"session_name"},
|
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.PoolNonpagedBytes = prometheus.NewDesc(
|
c.PoolNonpagedBytes = prometheus.NewDesc(
|
||||||
@@ -202,71 +193,39 @@ func (c *collector) Build() error {
|
|||||||
[]string{"session_name"},
|
[]string{"session_name"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
c.hServer, err = wtsapi32.WTSOpenServer("")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open WTS server: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectTSSessionCount(ctx, ch); err != nil {
|
if err := c.collectWTSSessions(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting terminal services session infos", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectTSSessionCounters(ctx, ch); err != nil {
|
if err := c.collectTSSessionCounters(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting terminal services session count metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting terminal services session count metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// only collect CollectionBrokerPerformance if host is a Connection Broker
|
// only collect CollectionBrokerPerformance if host is a Connection Broker
|
||||||
if c.connectionBrokerEnabled {
|
if c.connectionBrokerEnabled {
|
||||||
if desc, err := c.collectCollectionBrokerPerformanceCounter(ctx, ch); err != nil {
|
if err := c.collectCollectionBrokerPerformanceCounter(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting Connection Broker performance metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting Connection Broker performance metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type perflibTerminalServices struct {
|
|
||||||
ActiveSessions float64 `perflib:"Active Sessions"`
|
|
||||||
InactiveSessions float64 `perflib:"Inactive Sessions"`
|
|
||||||
TotalSessions float64 `perflib:"Total Sessions"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *collector) collectTSSessionCount(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
|
||||||
dst := make([]perflibTerminalServices, 0)
|
|
||||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Terminal Services"], &dst, c.logger)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(dst) == 0 {
|
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
|
||||||
}
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.LocalSessionCount,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
dst[0].ActiveSessions,
|
|
||||||
"active",
|
|
||||||
)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.LocalSessionCount,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
dst[0].InactiveSessions,
|
|
||||||
"inactive",
|
|
||||||
)
|
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
|
||||||
c.LocalSessionCount,
|
|
||||||
prometheus.GaugeValue,
|
|
||||||
dst[0].TotalSessions,
|
|
||||||
"total",
|
|
||||||
)
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type perflibTerminalServicesSession struct {
|
type perflibTerminalServicesSession struct {
|
||||||
Name string
|
Name string
|
||||||
HandleCount float64 `perflib:"Handle Count"`
|
HandleCount float64 `perflib:"Handle Count"`
|
||||||
@@ -286,11 +245,11 @@ type perflibTerminalServicesSession struct {
|
|||||||
WorkingSetPeak float64 `perflib:"Working Set Peak"`
|
WorkingSetPeak float64 `perflib:"Working Set Peak"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectTSSessionCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectTSSessionCounters(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
dst := make([]perflibTerminalServicesSession, 0)
|
dst := make([]perflibTerminalServicesSession, 0)
|
||||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Terminal Services Session"], &dst, c.logger)
|
err := perflib.UnmarshalObject(ctx.PerfObjects["Terminal Services Session"], &dst, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
names := make(map[string]bool)
|
names := make(map[string]bool)
|
||||||
|
|
||||||
@@ -331,22 +290,25 @@ func (c *collector) collectTSSessionCounters(ctx *types.ScrapeContext, ch chan<-
|
|||||||
d.Name,
|
d.Name,
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PercentPrivilegedTime,
|
c.PercentCPUTime,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.PercentPrivilegedTime,
|
d.PercentPrivilegedTime,
|
||||||
d.Name,
|
d.Name,
|
||||||
|
"privileged",
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PercentProcessorTime,
|
c.PercentCPUTime,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.PercentProcessorTime,
|
d.PercentProcessorTime,
|
||||||
d.Name,
|
d.Name,
|
||||||
|
"processor",
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PercentUserTime,
|
c.PercentCPUTime,
|
||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
d.PercentUserTime,
|
d.PercentUserTime,
|
||||||
d.Name,
|
d.Name,
|
||||||
|
"user",
|
||||||
)
|
)
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.PoolNonpagedBytes,
|
c.PoolNonpagedBytes,
|
||||||
@@ -397,7 +359,7 @@ func (c *collector) collectTSSessionCounters(ctx *types.ScrapeContext, ch chan<-
|
|||||||
d.Name,
|
d.Name,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type perflibRemoteDesktopConnectionBrokerCounterset struct {
|
type perflibRemoteDesktopConnectionBrokerCounterset struct {
|
||||||
@@ -406,14 +368,14 @@ type perflibRemoteDesktopConnectionBrokerCounterset struct {
|
|||||||
FailedConnections float64 `perflib:"Failed Connections"`
|
FailedConnections float64 `perflib:"Failed Connections"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectCollectionBrokerPerformanceCounter(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectCollectionBrokerPerformanceCounter(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
dst := make([]perflibRemoteDesktopConnectionBrokerCounterset, 0)
|
dst := make([]perflibRemoteDesktopConnectionBrokerCounterset, 0)
|
||||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Remote Desktop Connection Broker Counterset"], &dst, c.logger)
|
err := perflib.UnmarshalObject(ctx.PerfObjects["Remote Desktop Connection Broker Counterset"], &dst, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -437,5 +399,38 @@ func (c *collector) collectCollectionBrokerPerformanceCounter(ctx *types.ScrapeC
|
|||||||
"Failed",
|
"Failed",
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *collector) collectWTSSessions(ch chan<- prometheus.Metric) error {
|
||||||
|
sessions, err := wtsapi32.WTSEnumerateSessionsEx(c.hServer, c.logger)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to enumerate WTS sessions: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, session := range sessions {
|
||||||
|
userName := session.UserName
|
||||||
|
if session.DomainName != "" {
|
||||||
|
userName = fmt.Sprintf("%s\\%s", session.DomainName, session.UserName)
|
||||||
|
}
|
||||||
|
|
||||||
|
for stateID, stateName := range wtsapi32.WTSSessionStates {
|
||||||
|
isState := 0.0
|
||||||
|
if session.State == stateID {
|
||||||
|
isState = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.SessionInfo,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
isState,
|
||||||
|
strings.Replace(session.SessionName, "#", " ", -1),
|
||||||
|
userName,
|
||||||
|
session.HostName,
|
||||||
|
stateName,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkCollector(b *testing.B) {
|
func BenchmarkCollector(b *testing.B) {
|
||||||
|
|
||||||
testutils.FuncBenchmarkCollector(b, terminal_services.Name, terminal_services.NewWithFlags)
|
testutils.FuncBenchmarkCollector(b, terminal_services.Name, terminal_services.NewWithFlags)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
package textfile
|
package textfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@@ -100,7 +101,7 @@ func (c *collector) Build() error {
|
|||||||
c.directories = strings.Trim(*c.textFileDirectories, ",")
|
c.directories = strings.Trim(*c.textFileDirectories, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = level.Info(c.logger).Log("msg", fmt.Sprintf("textfile collector directories: %s", c.directories))
|
_ = level.Info(c.logger).Log("msg", "textfile collector directories: "+c.directories)
|
||||||
|
|
||||||
c.MtimeDesc = prometheus.NewDesc(
|
c.MtimeDesc = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, "textfile", "mtime_seconds"),
|
prometheus.BuildFQName(types.Namespace, "textfile", "mtime_seconds"),
|
||||||
@@ -296,12 +297,12 @@ func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
for _, directory := range strings.Split(c.directories, ",") {
|
for _, directory := range strings.Split(c.directories, ",") {
|
||||||
err := filepath.WalkDir(directory, func(path string, dirEntry os.DirEntry, err error) error {
|
err := filepath.WalkDir(directory, func(path string, dirEntry os.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error reading directory: %s", path), "err", err)
|
_ = level.Error(c.logger).Log("msg", "Error reading directory: "+path, "err", err)
|
||||||
errorMetric = 1.0
|
errorMetric = 1.0
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !dirEntry.IsDir() && strings.HasSuffix(dirEntry.Name(), ".prom") {
|
if !dirEntry.IsDir() && strings.HasSuffix(dirEntry.Name(), ".prom") {
|
||||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Processing file: %s", path))
|
_ = level.Debug(c.logger).Log("msg", "Processing file: "+path)
|
||||||
families_array, err := scrapeFile(path, c.logger)
|
families_array, err := scrapeFile(path, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error scraping file: %q. Skip File.", path), "err", err)
|
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error scraping file: %q. Skip File.", path), "err", err)
|
||||||
@@ -325,7 +326,7 @@ func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric)
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil && directory != "" {
|
if err != nil && directory != "" {
|
||||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error reading textfile collector directory: %s", c.directories), "err", err)
|
_ = level.Error(c.logger).Log("msg", "Error reading textfile collector directory: "+c.directories, "err", err)
|
||||||
errorMetric = 1.0
|
errorMetric = 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,24 +374,24 @@ func scrapeFile(path string, log log.Logger) ([]*dto.MetricFamily, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use temporary array to check for duplicates
|
// Use temporary array to check for duplicates
|
||||||
var families_array []*dto.MetricFamily
|
families_array := make([]*dto.MetricFamily, 0, len(parsedFamilies))
|
||||||
|
|
||||||
for _, mf := range parsedFamilies {
|
for _, mf := range parsedFamilies {
|
||||||
families_array = append(families_array, mf)
|
families_array = append(families_array, mf)
|
||||||
for _, m := range mf.Metric {
|
for _, m := range mf.Metric {
|
||||||
if m.TimestampMs != nil {
|
if m.TimestampMs != nil {
|
||||||
return nil, fmt.Errorf("textfile contains unsupported client-side timestamps")
|
return nil, errors.New("textfile contains unsupported client-side timestamps")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mf.Help == nil {
|
if mf.Help == nil {
|
||||||
help := fmt.Sprintf("Metric read from %s", path)
|
help := "Metric read from " + path
|
||||||
mf.Help = &help
|
mf.Help = &help
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If duplicate metrics are detected in a *single* file, skip processing of file metrics
|
// If duplicate metrics are detected in a *single* file, skip processing of file metrics
|
||||||
if duplicateMetricEntry(families_array) {
|
if duplicateMetricEntry(families_array) {
|
||||||
return nil, fmt.Errorf("duplicate metrics detected")
|
return nil, errors.New("duplicate metrics detected")
|
||||||
}
|
}
|
||||||
return families_array, nil
|
return families_array, nil
|
||||||
}
|
}
|
||||||
@@ -400,7 +401,7 @@ func checkBOM(encoding utfbom.Encoding) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf(encoding.String())
|
return errors.New(encoding.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultPath() string {
|
func getDefaultPath() string {
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if err := c.collect(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting thermalzone metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting thermalzone metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -98,16 +98,16 @@ type Win32_PerfRawData_Counters_ThermalZoneInformation struct {
|
|||||||
ThrottleReasons uint32
|
ThrottleReasons uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_Counters_ThermalZoneInformation
|
var dst []Win32_PerfRawData_Counters_ThermalZoneInformation
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThermalZone collector has been known to 'successfully' return an empty result.
|
// ThermalZone collector has been known to 'successfully' return an empty result.
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("Empty results set for collector")
|
return errors.New("Empty results set for collector")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, info := range dst {
|
for _, info := range dst {
|
||||||
@@ -134,5 +134,5 @@ func (c *collector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, erro
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ctx, ch); err != nil {
|
if err := c.collect(ctx, ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting time metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting time metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -118,10 +118,10 @@ type windowsTime struct {
|
|||||||
NTPServerOutgoingResponsesTotal float64 `perflib:"NTP Server Outgoing Responses"`
|
NTPServerOutgoingResponsesTotal float64 `perflib:"NTP Server Outgoing Responses"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
var dst []windowsTime // Single-instance class, array is required but will have single entry.
|
var dst []windowsTime // Single-instance class, array is required but will have single entry.
|
||||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Windows Time Service"], &dst, c.logger); err != nil {
|
if err := perflib.UnmarshalObject(ctx.PerfObjects["Windows Time Service"], &dst, c.logger); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -154,5 +154,5 @@ func (c *collector) collect(ctx *types.ScrapeContext, ch chan<- prometheus.Metri
|
|||||||
prometheus.CounterValue,
|
prometheus.CounterValue,
|
||||||
dst[0].NTPServerOutgoingResponsesTotal,
|
dst[0].NTPServerOutgoingResponsesTotal,
|
||||||
)
|
)
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,12 +190,12 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectMem(ch); err != nil {
|
if err := c.collectMem(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware memory metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware memory metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectCpu(ch); err != nil {
|
if err := c.collectCpu(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware cpu metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware cpu metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -226,14 +226,14 @@ type Win32_PerfRawData_vmGuestLib_VCPU struct {
|
|||||||
HostProcessorSpeedMHz uint64
|
HostProcessorSpeedMHz uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectMem(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectMem(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_vmGuestLib_VMem
|
var dst []Win32_PerfRawData_vmGuestLib_VMem
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -308,21 +308,21 @@ func (c *collector) collectMem(ch chan<- prometheus.Metric) (*prometheus.Desc, e
|
|||||||
mbToBytes(dst[0].MemUsedMB),
|
mbToBytes(dst[0].MemUsedMB),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mbToBytes(mb uint64) float64 {
|
func mbToBytes(mb uint64) float64 {
|
||||||
return float64(mb * 1024 * 1024)
|
return float64(mb * 1024 * 1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectCpu(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectCpu(ch chan<- prometheus.Metric) error {
|
||||||
var dst []Win32_PerfRawData_vmGuestLib_VCPU
|
var dst []Win32_PerfRawData_vmGuestLib_VCPU
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
return nil, errors.New("WMI query returned empty result set")
|
return errors.New("WMI query returned empty result set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -367,5 +367,5 @@ func (c *collector) collectCpu(ch chan<- prometheus.Metric) (*prometheus.Desc, e
|
|||||||
float64(dst[0].HostProcessorSpeedMHz),
|
float64(dst[0].HostProcessorSpeedMHz),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -570,52 +570,52 @@ func (c *collector) Build() error {
|
|||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
func (c *collector) Collect(_ *types.ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collectAudio(ch); err != nil {
|
if err := c.collectAudio(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast audio metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast audio metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectCdr(ch); err != nil {
|
if err := c.collectCdr(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast CDR metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast CDR metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectClipboard(ch); err != nil {
|
if err := c.collectClipboard(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast clipboard metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast clipboard metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectHtml5Mmr(ch); err != nil {
|
if err := c.collectHtml5Mmr(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast HTML5 MMR metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast HTML5 MMR metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectImaging(ch); err != nil {
|
if err := c.collectImaging(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast imaging metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast imaging metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectRtav(ch); err != nil {
|
if err := c.collectRtav(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast RTAV metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast RTAV metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectSerialPortandScanner(ch); err != nil {
|
if err := c.collectSerialPortandScanner(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast serial port and scanner metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast serial port and scanner metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectSession(ch); err != nil {
|
if err := c.collectSession(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectSkypeforBusinessControl(ch); err != nil {
|
if err := c.collectSkypeforBusinessControl(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast skype for business control metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast skype for business control metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectThinPrint(ch); err != nil {
|
if err := c.collectThinPrint(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast thin print metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast thin print metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectUsb(ch); err != nil {
|
if err := c.collectUsb(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast USB metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast USB metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if desc, err := c.collectWindowsMediaMmr(ch); err != nil {
|
if err := c.collectWindowsMediaMmr(ch); err != nil {
|
||||||
_ = level.Error(c.logger).Log("failed collecting vmware blast windows media MMR metrics", "desc", desc, "err", err)
|
_ = level.Error(c.logger).Log("msg", "failed collecting vmware blast windows media MMR metrics", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -726,16 +726,16 @@ type win32_PerfRawData_Counters_VMwareBlastWindowsMediaMMRCounters struct {
|
|||||||
TransmittedPackets uint32
|
TransmittedPackets uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectAudio(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectAudio(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastAudioCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastAudioCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -762,19 +762,19 @@ func (c *collector) collectAudio(ch chan<- prometheus.Metric) (*prometheus.Desc,
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectCdr(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectCdr(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastCDRCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastCDRCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -801,19 +801,19 @@ func (c *collector) collectCdr(ch chan<- prometheus.Metric) (*prometheus.Desc, e
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectClipboard(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectClipboard(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastClipboardCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastClipboardCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -840,19 +840,19 @@ func (c *collector) collectClipboard(ch chan<- prometheus.Metric) (*prometheus.D
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectHtml5Mmr(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectHtml5Mmr(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastHTML5MMRcounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastHTML5MMRcounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -879,19 +879,19 @@ func (c *collector) collectHtml5Mmr(ch chan<- prometheus.Metric) (*prometheus.De
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectImaging(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectImaging(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastImagingCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastImagingCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -966,19 +966,19 @@ func (c *collector) collectImaging(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectRtav(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectRtav(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastRTAVCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastRTAVCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1005,19 +1005,19 @@ func (c *collector) collectRtav(ch chan<- prometheus.Metric) (*prometheus.Desc,
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectSerialPortandScanner(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectSerialPortandScanner(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastSerialPortandScannerCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastSerialPortandScannerCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1044,19 +1044,19 @@ func (c *collector) collectSerialPortandScanner(ch chan<- prometheus.Metric) (*p
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectSession(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectSession(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastSessionCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastSessionCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1161,19 +1161,19 @@ func (c *collector) collectSession(ch chan<- prometheus.Metric) (*prometheus.Des
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectSkypeforBusinessControl(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectSkypeforBusinessControl(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastSkypeforBusinessControlCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastSkypeforBusinessControlCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1200,19 +1200,19 @@ func (c *collector) collectSkypeforBusinessControl(ch chan<- prometheus.Metric)
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectThinPrint(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectThinPrint(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastThinPrintCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastThinPrintCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1239,19 +1239,19 @@ func (c *collector) collectThinPrint(ch chan<- prometheus.Metric) (*prometheus.D
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectUsb(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectUsb(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastUSBCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastUSBCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1278,19 +1278,19 @@ func (c *collector) collectUsb(ch chan<- prometheus.Metric) (*prometheus.Desc, e
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *collector) collectWindowsMediaMmr(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
func (c *collector) collectWindowsMediaMmr(ch chan<- prometheus.Metric) error {
|
||||||
var dst []win32_PerfRawData_Counters_VMwareBlastWindowsMediaMMRCounters
|
var dst []win32_PerfRawData_Counters_VMwareBlastWindowsMediaMMRCounters
|
||||||
q := wmi.QueryAll(&dst, c.logger)
|
q := wmi.QueryAll(&dst, c.logger)
|
||||||
if err := wmi.Query(q, &dst); err != nil {
|
if err := wmi.Query(q, &dst); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dst) == 0 {
|
if len(dst) == 0 {
|
||||||
// It's possible for these classes to legitimately return null when queried
|
// It's possible for these classes to legitimately return null when queried
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
@@ -1317,5 +1317,5 @@ func (c *collector) collectWindowsMediaMmr(ch chan<- prometheus.Metric) (*promet
|
|||||||
float64(dst[0].TransmittedPackets),
|
float64(dst[0].TransmittedPackets),
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
// flatten flattens the nested struct.
|
// flatten flattens the nested struct.
|
||||||
//
|
//
|
||||||
@@ -46,7 +49,7 @@ func flattenSlice(data []interface{}) map[string]string {
|
|||||||
ret[fmt.Sprintf("%d,%s", idx, fk)] = fv
|
ret[fmt.Sprintf("%d,%s", idx, fk)] = fv
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ret[fmt.Sprint(idx)] = fmt.Sprint(typed)
|
ret[strconv.Itoa(idx)] = fmt.Sprint(typed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
52
pkg/headers/kernel32/kernel32.go
Normal file
52
pkg/headers/kernel32/kernel32.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package kernel32
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
|
procGetDynamicTimeZoneInformationSys = kernel32.NewProc("GetDynamicTimeZoneInformation")
|
||||||
|
)
|
||||||
|
|
||||||
|
// SYSTEMTIME contains a date and time.
|
||||||
|
// 📑 https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
||||||
|
type SYSTEMTIME struct {
|
||||||
|
WYear uint16
|
||||||
|
WMonth uint16
|
||||||
|
WDayOfWeek uint16
|
||||||
|
WDay uint16
|
||||||
|
WHour uint16
|
||||||
|
WMinute uint16
|
||||||
|
WSecond uint16
|
||||||
|
WMilliseconds uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// DynamicTimezoneInformation contains the current dynamic daylight time settings.
|
||||||
|
// 📑 https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/ns-timezoneapi-dynamic_time_zone_information
|
||||||
|
type DynamicTimezoneInformation struct {
|
||||||
|
Bias int32
|
||||||
|
standardName [32]uint16
|
||||||
|
StandardDate SYSTEMTIME
|
||||||
|
StandardBias int32
|
||||||
|
DaylightName [32]uint16
|
||||||
|
DaylightDate SYSTEMTIME
|
||||||
|
DaylightBias int32
|
||||||
|
TimeZoneKeyName [128]uint16
|
||||||
|
DynamicDaylightTimeDisabled uint8 // BOOLEAN
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDynamicTimeZoneInformation retrieves the current dynamic daylight time settings.
|
||||||
|
// 📑 https://docs.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-getdynamictimezoneinformation
|
||||||
|
func GetDynamicTimeZoneInformation() (DynamicTimezoneInformation, error) {
|
||||||
|
var tzi DynamicTimezoneInformation
|
||||||
|
|
||||||
|
r0, _, err := syscall.SyscallN(procGetDynamicTimeZoneInformationSys.Addr(), uintptr(unsafe.Pointer(&tzi)))
|
||||||
|
if uint32(r0) == 0xffffffff {
|
||||||
|
return tzi, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tzi, nil
|
||||||
|
}
|
||||||
40
pkg/headers/slc/slc.go
Normal file
40
pkg/headers/slc/slc.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package slc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slc = windows.NewLazySystemDLL("slc.dll")
|
||||||
|
procSLIsWindowsGenuineLocal = slc.NewProc("SLIsWindowsGenuineLocal")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Define SL_GENUINE_STATE enumeration
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/slpublic/ne-slpublic-sl_genuine_state
|
||||||
|
type SL_GENUINE_STATE uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
SL_GEN_STATE_IS_GENUINE SL_GENUINE_STATE = iota
|
||||||
|
SL_GEN_STATE_INVALID_LICENSE
|
||||||
|
SL_GEN_STATE_TAMPERED
|
||||||
|
SL_GEN_STATE_OFFLINE
|
||||||
|
SL_GEN_STATE_LAST
|
||||||
|
)
|
||||||
|
|
||||||
|
// SLIsWindowsGenuineLocal function wrapper
|
||||||
|
func SLIsWindowsGenuineLocal() (SL_GENUINE_STATE, error) {
|
||||||
|
var genuineState SL_GENUINE_STATE
|
||||||
|
|
||||||
|
_, _, err := procSLIsWindowsGenuineLocal.Call(
|
||||||
|
uintptr(unsafe.Pointer(&genuineState)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if !errors.Is(err, windows.NTE_OP_OK) {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return genuineState, nil
|
||||||
|
}
|
||||||
202
pkg/headers/wtsapi32/wtsapi32.go
Normal file
202
pkg/headers/wtsapi32/wtsapi32.go
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
package wtsapi32
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/go-kit/log"
|
||||||
|
"github.com/go-kit/log/level"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WTSTypeClass int
|
||||||
|
|
||||||
|
// The valid values for the WTSTypeClass enumeration
|
||||||
|
const (
|
||||||
|
WTSTypeProcessInfoLevel0 WTSTypeClass = iota
|
||||||
|
WTSTypeProcessInfoLevel1
|
||||||
|
WTSTypeSessionInfoLevel1
|
||||||
|
)
|
||||||
|
|
||||||
|
type WTSConnectState uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// wtsActive A user is logged on to the WinStation. This state occurs when a user is signed in and actively connected to the device.
|
||||||
|
wtsActive WTSConnectState = iota
|
||||||
|
// wtsConnected The WinStation is connected to the client.
|
||||||
|
wtsConnected
|
||||||
|
// wtsConnectQuery The WinStation is in the process of connecting to the client.
|
||||||
|
wtsConnectQuery
|
||||||
|
// wtsShadow The WinStation is shadowing another WinStation.
|
||||||
|
wtsShadow
|
||||||
|
// wtsDisconnected The WinStation is active but the client is disconnected.
|
||||||
|
// This state occurs when a user is signed in but not actively connected to the device, such as when the user has chosen to exit to the lock screen.
|
||||||
|
wtsDisconnected
|
||||||
|
// wtsIdle The WinStation is waiting for a client to connect.
|
||||||
|
wtsIdle
|
||||||
|
// wtsListen The WinStation is listening for a connection. A listener session waits for requests for new client connections.
|
||||||
|
// No user is logged on a listener session. A listener session cannot be reset, shadowed, or changed to a regular client session.
|
||||||
|
wtsListen
|
||||||
|
// wtsReset The WinStation is being reset.
|
||||||
|
wtsReset
|
||||||
|
// wtsDown The WinStation is down due to an error.
|
||||||
|
wtsDown
|
||||||
|
// wtsInit The WinStation is initializing.
|
||||||
|
wtsInit
|
||||||
|
)
|
||||||
|
|
||||||
|
// WTSSessionInfo1w contains information about a session on a Remote Desktop Session Host (RD Session Host) server.
|
||||||
|
// docs: https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/ns-wtsapi32-wts_session_info_1w
|
||||||
|
type wtsSessionInfo1 struct {
|
||||||
|
// ExecEnvID An identifier that uniquely identifies the session within the list of sessions returned by the WTSEnumerateSessionsEx function.
|
||||||
|
ExecEnvID uint32
|
||||||
|
// State A value of the WTSConnectState enumeration type that specifies the connection state of a Remote Desktop Services session.
|
||||||
|
State uint32
|
||||||
|
// SessionID A session identifier assigned by the RD Session Host server, RD Virtualization Host server, or virtual machine.
|
||||||
|
SessionID uint32
|
||||||
|
// pSessionName A pointer to a null-terminated string that contains the name of this session. For example, "services", "console", or "RDP-Tcp#0".
|
||||||
|
pSessionName *uint16
|
||||||
|
// pHostName A pointer to a null-terminated string that contains the name of the computer that the session is running on.
|
||||||
|
// If the session is running directly on an RD Session Host server or RD Virtualization Host server, the string contains NULL.
|
||||||
|
// If the session is running on a virtual machine, the string contains the name of the virtual machine.
|
||||||
|
pHostName *uint16
|
||||||
|
// pUserName A pointer to a null-terminated string that contains the name of the user who is logged on to the session.
|
||||||
|
// If no user is logged on to the session, the string contains NULL.
|
||||||
|
pUserName *uint16
|
||||||
|
// pDomainName A pointer to a null-terminated string that contains the domain name of the user who is logged on to the session.
|
||||||
|
// If no user is logged on to the session, the string contains NULL.
|
||||||
|
pDomainName *uint16
|
||||||
|
// pFarmName A pointer to a null-terminated string that contains the name of the farm that the virtual machine is joined to.
|
||||||
|
// If the session is not running on a virtual machine that is joined to a farm, the string contains NULL.
|
||||||
|
pFarmName *uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type WTSSession struct {
|
||||||
|
ExecEnvID uint32
|
||||||
|
State WTSConnectState
|
||||||
|
SessionID uint32
|
||||||
|
SessionName string
|
||||||
|
HostName string
|
||||||
|
UserName string
|
||||||
|
DomainName string
|
||||||
|
FarmName string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
wtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
|
||||||
|
|
||||||
|
procWTSOpenServerEx = wtsapi32.NewProc("WTSOpenServerExW")
|
||||||
|
procWTSEnumerateSessionsEx = wtsapi32.NewProc("WTSEnumerateSessionsExW")
|
||||||
|
procWTSFreeMemoryEx = wtsapi32.NewProc("WTSFreeMemoryExW")
|
||||||
|
procWTSCloseServer = wtsapi32.NewProc("WTSCloseServer")
|
||||||
|
|
||||||
|
WTSSessionStates = map[WTSConnectState]string{
|
||||||
|
wtsActive: "active",
|
||||||
|
wtsConnected: "connected",
|
||||||
|
wtsConnectQuery: "connect_query",
|
||||||
|
wtsShadow: "shadow",
|
||||||
|
wtsDisconnected: "disconnected",
|
||||||
|
wtsIdle: "idle",
|
||||||
|
wtsListen: "listen",
|
||||||
|
wtsReset: "reset",
|
||||||
|
wtsDown: "down",
|
||||||
|
wtsInit: "init",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func WTSOpenServer(server string) (syscall.Handle, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
serverName *uint16
|
||||||
|
)
|
||||||
|
|
||||||
|
if server != "" {
|
||||||
|
serverName, err = syscall.UTF16PtrFromString(server)
|
||||||
|
if err != nil {
|
||||||
|
return syscall.InvalidHandle, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r1, _, err := procWTSOpenServerEx.Call(uintptr(unsafe.Pointer(serverName)))
|
||||||
|
serverHandle := syscall.Handle(r1)
|
||||||
|
|
||||||
|
if serverHandle == syscall.InvalidHandle {
|
||||||
|
return syscall.InvalidHandle, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverHandle, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WTSCloseServer(server syscall.Handle) error {
|
||||||
|
_, _, err := procWTSCloseServer.Call(uintptr(server))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to close server: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func WTSFreeMemoryEx(class WTSTypeClass, pMemory uintptr, NumberOfEntries uint32) error {
|
||||||
|
r1, _, err := procWTSFreeMemoryEx.Call(
|
||||||
|
uintptr(class),
|
||||||
|
pMemory,
|
||||||
|
uintptr(NumberOfEntries),
|
||||||
|
)
|
||||||
|
|
||||||
|
if r1 != 1 {
|
||||||
|
return fmt.Errorf("failed to free memory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WTSEnumerateSessionsEx(server syscall.Handle, logger log.Logger) ([]WTSSession, error) {
|
||||||
|
var sessionInfoPointer uintptr
|
||||||
|
var count uint32
|
||||||
|
|
||||||
|
pLevel := uint32(1)
|
||||||
|
r1, _, err := procWTSEnumerateSessionsEx.Call(
|
||||||
|
uintptr(server),
|
||||||
|
uintptr(unsafe.Pointer(&pLevel)),
|
||||||
|
uintptr(0),
|
||||||
|
uintptr(unsafe.Pointer(&sessionInfoPointer)),
|
||||||
|
uintptr(unsafe.Pointer(&count)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if r1 != 1 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if sessionInfoPointer != 0 {
|
||||||
|
defer func(class WTSTypeClass, pMemory uintptr, NumberOfEntries uint32) {
|
||||||
|
err := WTSFreeMemoryEx(class, pMemory, NumberOfEntries)
|
||||||
|
if err != nil {
|
||||||
|
_ = level.Error(logger).Log("msg", "failed to free memory", "err", fmt.Errorf("WTSEnumerateSessionsEx: %w", err))
|
||||||
|
}
|
||||||
|
}(WTSTypeSessionInfoLevel1, sessionInfoPointer, count)
|
||||||
|
}
|
||||||
|
|
||||||
|
var sizeTest wtsSessionInfo1
|
||||||
|
sessionSize := unsafe.Sizeof(sizeTest)
|
||||||
|
|
||||||
|
sessions := make([]WTSSession, 0, count)
|
||||||
|
for i := uint32(0); i < count; i++ {
|
||||||
|
curPtr := unsafe.Pointer(sessionInfoPointer + (uintptr(i) * sessionSize))
|
||||||
|
data := (*wtsSessionInfo1)(curPtr)
|
||||||
|
|
||||||
|
sessionInfo := WTSSession{
|
||||||
|
ExecEnvID: data.ExecEnvID,
|
||||||
|
State: WTSConnectState(data.State),
|
||||||
|
SessionID: data.SessionID,
|
||||||
|
SessionName: windows.UTF16PtrToString(data.pSessionName),
|
||||||
|
HostName: windows.UTF16PtrToString(data.pHostName),
|
||||||
|
UserName: windows.UTF16PtrToString(data.pUserName),
|
||||||
|
DomainName: windows.UTF16PtrToString(data.pDomainName),
|
||||||
|
FarmName: windows.UTF16PtrToString(data.pFarmName),
|
||||||
|
}
|
||||||
|
sessions = append(sessions, sessionInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessions, nil
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user