mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +00:00
Compare commits
77 Commits
v0.29.0-rc
...
v0.30.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f29fc8a9c | ||
|
|
e6a15d4ec4 | ||
|
|
6206b695c6 | ||
|
|
b209ab6d6a | ||
|
|
78bd720e88 | ||
|
|
a4ec0a96f1 | ||
|
|
7a9a4e5831 | ||
|
|
df8513ab8e | ||
|
|
1956330ac4 | ||
|
|
baa4dc16ae | ||
|
|
d13d726453 | ||
|
|
31bcf42473 | ||
|
|
f332361723 | ||
|
|
b4f50c542c | ||
|
|
b53f18bcc6 | ||
|
|
eeb7955f5e | ||
|
|
55181f5bac | ||
|
|
e6c9253f15 | ||
|
|
b26ae86992 | ||
|
|
004f8da0ef | ||
|
|
65f41b3582 | ||
|
|
be67d853aa | ||
|
|
bf233ad3e3 | ||
|
|
45d3eabab9 | ||
|
|
c4f5d58a3e | ||
|
|
582d8dd29c | ||
|
|
abc5388cab | ||
|
|
fd9eb6d877 | ||
|
|
bad8ba225a | ||
|
|
ce2df385a6 | ||
|
|
92b7e445e1 | ||
|
|
332b0a8a1c | ||
|
|
73755b8bfe | ||
|
|
25d90212ce | ||
|
|
d1517d8398 | ||
|
|
7500ad6a83 | ||
|
|
a0159b333e | ||
|
|
22fdb33b4c | ||
|
|
f46f9082f9 | ||
|
|
028f7aa823 | ||
|
|
545bf77326 | ||
|
|
90ac0b269e | ||
|
|
72df5154fc | ||
|
|
4ee03c4528 | ||
|
|
2ef1a5fdf1 | ||
|
|
efb20b1e31 | ||
|
|
ab33f3c49c | ||
|
|
5952c51a39 | ||
|
|
2a9a11bd01 | ||
|
|
79baf9921d | ||
|
|
7e9976efd3 | ||
|
|
5d95610c84 | ||
|
|
bcfe6df24d | ||
|
|
70156cd106 | ||
|
|
e6ef2de40c | ||
|
|
0a78909cf6 | ||
|
|
2155d34779 | ||
|
|
1caef5cc12 | ||
|
|
14910efd4f | ||
|
|
48e0e11063 | ||
|
|
996080c1e9 | ||
|
|
e6aaf91df1 | ||
|
|
b67b930ffc | ||
|
|
a1defadf1e | ||
|
|
01e809315c | ||
|
|
798bf32dec | ||
|
|
622813343f | ||
|
|
65d19f433e | ||
|
|
2d334e4df0 | ||
|
|
f442d6e22a | ||
|
|
d43f6ffdec | ||
|
|
9bea340c44 | ||
|
|
2635e5d8eb | ||
|
|
41ff5729df | ||
|
|
6097432d87 | ||
|
|
5f36a81613 | ||
|
|
2e4ba9984d |
22
.github/workflows/container_description.yml
vendored
22
.github/workflows/container_description.yml
vendored
@@ -33,25 +33,3 @@ jobs:
|
||||
# Empty string results in README-containers.md being pushed if it
|
||||
# exists. Otherwise, README.md is pushed.
|
||||
readme_file: ''
|
||||
|
||||
PushQuayIoReadme:
|
||||
runs-on: ubuntu-latest
|
||||
name: Push README to quay.io
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- name: Set quay.io org name
|
||||
run: echo "DOCKER_REPO=$(echo quay.io/${GITHUB_REPOSITORY_OWNER} | tr -d '-')" >> $GITHUB_ENV
|
||||
- name: Set quay.io repo name
|
||||
run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
|
||||
- name: Push README to quay.io
|
||||
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
|
||||
env:
|
||||
DOCKER_APIKEY: ${{ secrets.QUAY_IO_API_TOKEN }}
|
||||
with:
|
||||
destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
|
||||
provider: quay
|
||||
# Empty string results in README-containers.md being pushed if it
|
||||
# exists. Otherwise, README.md is pushed.
|
||||
readme_file: ''
|
||||
|
||||
2
.github/workflows/pr-check.yaml
vendored
2
.github/workflows/pr-check.yaml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
- name: check
|
||||
run: |
|
||||
PR_TITLE_PREFIX=$(echo "$PR_TITLE" | cut -d':' -f1)
|
||||
if [[ -d "pkg/collector/$PR_TITLE_PREFIX" ]] ||[[ -d "pkg/$PR_TITLE_PREFIX" ]] || [[ -d "$PR_TITLE_PREFIX" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(docs)" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Synchronize common files from prometheus/prometheus" ]]; then
|
||||
if [[ -d "internal/collector/$PR_TITLE_PREFIX" ]] || [[ -d "internal/$PR_TITLE_PREFIX" ]] || [[ -d "pkg/$PR_TITLE_PREFIX" ]] || [[ -d "$PR_TITLE_PREFIX" ]] || [[ "$PR_TITLE_PREFIX" == "docs" ]] || [[ "$PR_TITLE_PREFIX" == "ci" ]] || [[ "$PR_TITLE_PREFIX" == "revert" ]] || [[ "$PR_TITLE_PREFIX" == "fix" ]] || [[ "$PR_TITLE_PREFIX" == "feat" ]] || [[ "$PR_TITLE_PREFIX" == "chore" ]] || [[ "$PR_TITLE_PREFIX" == "chore(docs)" ]] || [[ "$PR_TITLE_PREFIX" == "chore(deps)" ]] || [[ "$PR_TITLE_PREFIX" == "*" ]] || [[ "$PR_TITLE_PREFIX" == "Synchronize common files from prometheus/prometheus" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
115
.github/workflows/release.yml
vendored
115
.github/workflows/release.yml
vendored
@@ -6,6 +6,7 @@ on:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
@@ -16,10 +17,7 @@ permissions:
|
||||
packages: write
|
||||
|
||||
env:
|
||||
VERSION_PROMU: '0.14.0'
|
||||
VERSION_CONTAINERD: '1.7.21'
|
||||
VERSION_BUILDKIT: '0.15.2'
|
||||
VERSION_BUILDX: '0.16.2'
|
||||
VERSION_PROMU: '0.17.0'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -33,27 +31,6 @@ jobs:
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
# https://github.com/pl4nty/Windows-Containers/blob/Main/helpful_tools/Install-BuildKit-GitHubActions/workflow.yaml
|
||||
- name: Setup containerd
|
||||
run: |
|
||||
curl.exe -L https://github.com/containerd/containerd/releases/download/v${{ env.VERSION_CONTAINERD }}/containerd-${{ env.VERSION_CONTAINERD }}-windows-amd64.tar.gz -o containerd.tar.gz
|
||||
tar.exe xvf containerd.tar.gz
|
||||
.\bin\containerd.exe --register-service
|
||||
Start-Service containerd
|
||||
- name: Setup BuildKit
|
||||
run: |
|
||||
curl.exe -L https://github.com/moby/buildkit/releases/download/v${{ env.VERSION_BUILDKIT }}/buildkit-v${{ env.VERSION_BUILDKIT }}.windows-amd64.tar.gz -o buildkit.tar.gz
|
||||
tar.exe xvf buildkit.tar.gz
|
||||
|
||||
.\bin\buildkitd.exe --register-service
|
||||
Start-Service buildkitd
|
||||
- name: Setup Docker Buildx
|
||||
run: |
|
||||
curl.exe -L https://github.com/docker/buildx/releases/download/v${{ env.VERSION_BUILDX }}/buildx-v${{ env.VERSION_BUILDX }}.windows-amd64.exe -o $env:ProgramData\Docker\cli-plugins\docker-buildx.exe
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver: remote
|
||||
endpoint: npipe:////./pipe/buildkitd
|
||||
- name: Install WiX
|
||||
run: dotnet tool install --global wix
|
||||
|
||||
@@ -75,32 +52,32 @@ jobs:
|
||||
- name: Build
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
|
||||
$Version = git describe --tags --always
|
||||
$Version = $Version -replace 'v', ''
|
||||
# '+' symbols are invalid characters in image tags
|
||||
$Version = $Version -replace '\+', '_'
|
||||
$Version | Set-Content VERSION -PassThru
|
||||
|
||||
|
||||
make build-all
|
||||
|
||||
|
||||
# GH requires all files to have different names, so add version/arch to differentiate
|
||||
foreach($Arch in "amd64", "arm64") {
|
||||
Move-Item output\$Arch\windows_exporter.exe output\windows_exporter-$Version-$Arch.exe
|
||||
}
|
||||
|
||||
|
||||
Get-ChildItem -Path output
|
||||
|
||||
- name: Build Release Artifacts
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Version = Get-Content VERSION
|
||||
|
||||
|
||||
foreach($Arch in "amd64", "arm64") {
|
||||
Write-Host "Building windows_exporter $Version msi for $Arch"
|
||||
.\installer\build.ps1 -PathToExecutable .\output\windows_exporter-$Version-$Arch.exe -Version $Version -Arch "$Arch"
|
||||
}
|
||||
|
||||
|
||||
Move-Item installer\*.msi output\
|
||||
Get-ChildItem -Path output\
|
||||
|
||||
@@ -114,16 +91,27 @@ jobs:
|
||||
output\windows_exporter-*.exe
|
||||
output\windows_exporter-*.msi
|
||||
|
||||
- name: Build Docker Artifacts
|
||||
run: make build-all
|
||||
- name: Release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
VERSION: >-
|
||||
${{
|
||||
startsWith(github.ref, 'refs/tags/') && 'latest' ||
|
||||
(
|
||||
github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || github.ref_name
|
||||
)
|
||||
}}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
$TagName = $env:GITHUB_REF -replace 'refs/tags/', ''
|
||||
Get-ChildItem -Path output\* -Include @('windows_exporter*.msi', 'windows_exporter*.exe', 'sha256sums.txt') | Foreach-Object {gh release upload $TagName $_}
|
||||
docker:
|
||||
name: Build docker images
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: windows_exporter_binaries
|
||||
|
||||
- name: Login to Docker Hub
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -137,8 +125,8 @@ jobs:
|
||||
# uses: docker/login-action@v3
|
||||
# with:
|
||||
# registry: quay.io
|
||||
# username: 'robot'
|
||||
# password: ${{ secrets.QUAY_IO_API_TOKEN }}
|
||||
# username: ${{ secrets.QUAY_USER }}
|
||||
# password: ${{ secrets.QUAY_PASS }}
|
||||
|
||||
- name: Login to GitHub container registry
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -148,19 +136,32 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Push Latest image
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VERSION: ${{ startsWith(github.ref, 'refs/tags/') && 'latest' || github.ref_name }}
|
||||
run: |
|
||||
make push-all
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/prometheus-community/windows-exporter
|
||||
docker.io/prometheuscommunity/windows-exporter
|
||||
# quay.io/prometheuscommunity/windows-exporter
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
labels: |
|
||||
org.opencontainers.image.title=windows_exporter
|
||||
org.opencontainers.image.description=A Prometheus exporter for Windows machines.
|
||||
org.opencontainers.image.vendor=The Prometheus Community
|
||||
org.opencontainers.image.licenses=MIT
|
||||
|
||||
- name: Release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
$TagName = $env:GITHUB_REF -replace 'refs/tags/', ''
|
||||
Get-ChildItem -Path output\* -Include @('windows_exporter*.msi', 'windows_exporter*.exe', 'sha256sums.txt') | Foreach-Object {gh release upload $TagName $_}
|
||||
make push-all
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: windows/amd64
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,4 +8,5 @@ output/
|
||||
*.syso
|
||||
installer/*.msi
|
||||
installer/*.wixpdb
|
||||
local/
|
||||
local/
|
||||
!.idea/inspectionProfiles/Project_Default.xml
|
||||
|
||||
@@ -15,7 +15,9 @@ linters:
|
||||
- gocognit
|
||||
- goconst
|
||||
- gocyclo
|
||||
- godot
|
||||
- gomnd
|
||||
- paralleltest
|
||||
- lll
|
||||
- maintidx
|
||||
- mnd
|
||||
@@ -29,11 +31,12 @@ run:
|
||||
linters-settings:
|
||||
gosec:
|
||||
excludes:
|
||||
- G101 # Potential hardcoded credentials
|
||||
- G115 # integer overflow conversion
|
||||
|
||||
gci:
|
||||
sections:
|
||||
- prefix(github.com/prometheus-community/windows_exporter/pkg/initiate)
|
||||
- prefix(github.com/prometheus-community/windows_exporter/internal/windowsservice)
|
||||
- standard # Standard section: captures all standard packages.
|
||||
- default # Default section: contains all imports that could not be matched to another section type.
|
||||
custom-order: true
|
||||
@@ -45,13 +48,10 @@ linters-settings:
|
||||
# Support string case: `camel`, `pascal`, `kebab`, `snake`, `upperSnake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`, `header`
|
||||
json: camel
|
||||
yaml: snake
|
||||
gomoddirectives:
|
||||
replace-allow-list:
|
||||
- github.com/prometheus/common # https://github.com/prometheus/common/pull/694
|
||||
forbidigo:
|
||||
forbid:
|
||||
- "^(fmt\\.Print(|f|ln)|print|println)$"
|
||||
- p: "^syscall\\..*$"
|
||||
- p: "^syscall\\.(.{1,7}|.{7}[^N]|.{9,})$"
|
||||
msg: use golang.org/x/sys/windows instead of syscall
|
||||
- p: "^windows\\.NewLazyDLL$"
|
||||
msg: use NewLazySystemDLL instead NewLazyDLL
|
||||
@@ -85,7 +85,7 @@ issues:
|
||||
- text: "don't use ALL_CAPS in Go names; use CamelCase"
|
||||
linters:
|
||||
- revive
|
||||
- path: pkg/perflib/
|
||||
- path: internal/perfdata/v1/
|
||||
linters:
|
||||
- godox
|
||||
- stylecheck
|
||||
|
||||
@@ -2,6 +2,7 @@ go:
|
||||
# Whenever the Go version is updated here,
|
||||
# .github/workflows should also be updated.
|
||||
version: 1.23
|
||||
cgo: false
|
||||
repository:
|
||||
path: github.com/prometheus-community/windows_exporter
|
||||
build:
|
||||
@@ -21,4 +22,5 @@ tarball:
|
||||
- LICENSE
|
||||
crossbuild:
|
||||
platforms:
|
||||
- windows
|
||||
- windows/amd64
|
||||
- windows/arm64
|
||||
|
||||
16
Dockerfile
16
Dockerfile
@@ -1,9 +1,13 @@
|
||||
# Note this image doesn't really matter for hostprocess but it is good to build per OS version
|
||||
# the files in the image are copied to $env:CONTAINER_SANDBOX_MOUNT_POINT on the host
|
||||
# but the file system is the Host NOT the container
|
||||
ARG BASE="mcr.microsoft.com/windows/nanoserver:ltsc2022"
|
||||
# mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0
|
||||
# Using this image as a base for HostProcess containers has a few advantages over using other base images for Windows containers including:
|
||||
# - Smaller image size
|
||||
# - OS compatibility (works on any Windows version that supports containers)
|
||||
|
||||
# This image MUST be built with docker buildx build (buildx) command on a Linux system.
|
||||
# Ref: https://github.com/microsoft/windows-host-process-containers-base-image
|
||||
|
||||
ARG BASE="mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0"
|
||||
FROM $BASE
|
||||
|
||||
ENV PATH="C:\Windows\system32;C:\Windows;"
|
||||
COPY output/amd64/windows_exporter.exe /windows_exporter.exe
|
||||
COPY windows_exporter*-amd64.exe /windows_exporter.exe
|
||||
ENTRYPOINT ["windows_exporter.exe"]
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Build this Docker Image on any platform with
|
||||
# docker buildx build -t a --platform=windows/amd64 .
|
||||
|
||||
ARG BASE=mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0
|
||||
|
||||
FROM --platform=$BUILDPLATFORM golang:1.21 as builder
|
||||
ARG TARGETARCH
|
||||
ARG TARGETOS
|
||||
|
||||
# Get dependencies
|
||||
WORKDIR /w
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
RUN go install github.com/prometheus/promu@latest
|
||||
|
||||
# Build windows_exporter
|
||||
COPY . ./
|
||||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH make windows_exporter.exe
|
||||
|
||||
FROM $BASE
|
||||
COPY --from=builder /w/windows_exporter.exe /windows_exporter.exe
|
||||
ENTRYPOINT ["windows_exporter.exe"]
|
||||
30
Makefile
30
Makefile
@@ -29,14 +29,14 @@ test:
|
||||
go test -v ./...
|
||||
|
||||
bench:
|
||||
go test -v -bench='benchmarkcollector' ./pkg/collector/{cpu,logical_disk,physical_disk,logon,memory,net,printer,process,service,system,tcp,time}
|
||||
go test -v -bench='benchmarkcollector' ./internal/collectors/{cpu,logical_disk,physical_disk,logon,memory,net,printer,process,service,system,tcp,time}
|
||||
|
||||
lint:
|
||||
golangci-lint -c .golangci.yaml run
|
||||
|
||||
.PHONY: e2e-test
|
||||
e2e-test: windows_exporter.exe
|
||||
pwsh -NonInteractive -ExecutionPolicy Bypass -File .\tools\end-to-end-test.ps1
|
||||
powershell -NonInteractive -ExecutionPolicy Bypass -File .\tools\end-to-end-test.ps1
|
||||
|
||||
.PHONY: promtool
|
||||
promtool: windows_exporter.exe
|
||||
@@ -64,31 +64,19 @@ build-hostprocess:
|
||||
sub-build-%:
|
||||
$(MAKE) OS=$* build-image
|
||||
|
||||
build-all: $(addprefix sub-build-,$(ALL_OS)) build-hostprocess
|
||||
|
||||
push:
|
||||
set -x; \
|
||||
for docker_repo in ${DOCKER_REPO}; do \
|
||||
for osversion in ${ALL_OS}; do \
|
||||
$(DOCKER) tag local/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion} $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||
$(DOCKER) push $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||
$(DOCKER) manifest create --amend $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||
full_version=`$(DOCKER) manifest inspect $(BASE_IMAGE):$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \
|
||||
$(DOCKER) manifest annotate --os windows --arch amd64 --os-version $${full_version} $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-$${osversion}; \
|
||||
done; \
|
||||
$(DOCKER) manifest push --purge $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION); \
|
||||
build-all: crossbuild
|
||||
@for docker_repo in ${DOCKER_REPO}; do \
|
||||
echo $(DOCKER) buildx build -f Dockerfile -t $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) .; \
|
||||
done
|
||||
|
||||
# We can't load the image into the local docker store, so we have to build and push it in one go
|
||||
push-hostprocess:
|
||||
set -x; \
|
||||
for docker_repo in ${DOCKER_REPO}; do \
|
||||
$(DOCKER) buildx build --push --build-arg=BASE=mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0 -f Dockerfile -t $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION)-hostprocess .; \
|
||||
push:
|
||||
@for docker_repo in ${DOCKER_REPO}; do \
|
||||
echo $(DOCKER) buildx build --push -f Dockerfile -t $${docker_repo}/$(DOCKER_IMAGE_NAME):$(VERSION) .; \
|
||||
done
|
||||
|
||||
.PHONY: push-all
|
||||
push-all: build-all
|
||||
$(MAKE) DOCKER_REPO="$(ALL_DOCKER_REPOS)" push # push-hostprocess - disabled until it works on Windows
|
||||
$(MAKE) DOCKER_REPO="$(ALL_DOCKER_REPOS)" push
|
||||
|
||||
# Mandatory target for container description sync action
|
||||
.PHONY: docker-repo-name
|
||||
|
||||
67
README.md
67
README.md
@@ -1,6 +1,12 @@
|
||||
# windows_exporter
|
||||
|
||||

|
||||
[](https://github.com/prometheus-community/windows_exporter)
|
||||
[](https://github.com/prometheus-community/windows_exporter)
|
||||
[](https://github.com/prometheus-community/windows_exporter/blob/master/LICENSE.txt)
|
||||
[](https://github.com/prometheus-community/windows_exporter/releases/latest)
|
||||
[](https://github.com/prometheus-community/windows_exporter/stargazers)
|
||||
[](https://github.com/prometheus-community/windows_exporter/releases/latest)
|
||||
[](https://goreportcard.com/report/github.com/prometheus-community/windows_exporter)
|
||||
|
||||
A Prometheus exporter for Windows machines.
|
||||
|
||||
@@ -14,35 +20,31 @@ Name | Description | Enabled by default
|
||||
[cache](docs/collector.cache.md) | Cache metrics |
|
||||
[cpu](docs/collector.cpu.md) | CPU usage | ✓
|
||||
[cpu_info](docs/collector.cpu_info.md) | CPU Information |
|
||||
[cs](docs/collector.cs.md) | "Computer System" metrics (system properties, num cpus/total memory) |
|
||||
[cs](docs/collector.cs.md) | "Computer System" metrics (system properties, num cpus/total memory) |
|
||||
[container](docs/collector.container.md) | Container metrics |
|
||||
[diskdrive](docs/collector.diskdrive.md) | Diskdrive metrics |
|
||||
[dfsr](docs/collector.dfsr.md) | DFSR metrics |
|
||||
[dhcp](docs/collector.dhcp.md) | DHCP Server |
|
||||
[dns](docs/collector.dns.md) | DNS Server |
|
||||
[exchange](docs/collector.exchange.md) | Exchange metrics |
|
||||
[filetime](docs/collector.filetime.md) | FileTime metrics |
|
||||
[fsrmquota](docs/collector.fsrmquota.md) | Microsoft File Server Resource Manager (FSRM) Quotas collector |
|
||||
[hyperv](docs/collector.hyperv.md) | Hyper-V hosts |
|
||||
[iis](docs/collector.iis.md) | IIS sites and applications |
|
||||
[license](docs/collector.license.md) | Windows license status |
|
||||
[license](docs/collector.license.md) | Windows license status |
|
||||
[logical_disk](docs/collector.logical_disk.md) | Logical disks, disk I/O | ✓
|
||||
[logon](docs/collector.logon.md) | User logon sessions |
|
||||
[memory](docs/collector.memory.md) | Memory usage metrics | ✓
|
||||
[mscluster](docs/collector.mscluster.md) | MSCluster metrics |
|
||||
[msmq](docs/collector.msmq.md) | MSMQ queues |
|
||||
[mssql](docs/collector.mssql.md) | [SQL Server Performance Objects](https://docs.microsoft.com/en-us/sql/relational-databases/performance-monitor/use-sql-server-objects#SQLServerPOs) metrics |
|
||||
[netframework_clrexceptions](docs/collector.netframework_clrexceptions.md) | .NET Framework CLR Exceptions |
|
||||
[netframework_clrinterop](docs/collector.netframework_clrinterop.md) | .NET Framework Interop Metrics |
|
||||
[netframework_clrjit](docs/collector.netframework_clrjit.md) | .NET Framework JIT metrics |
|
||||
[netframework_clrloading](docs/collector.netframework_clrloading.md) | .NET Framework CLR Loading metrics |
|
||||
[netframework_clrlocksandthreads](docs/collector.netframework_clrlocksandthreads.md) | .NET Framework locks and metrics threads |
|
||||
[netframework_clrmemory](docs/collector.netframework_clrmemory.md) | .NET Framework Memory metrics |
|
||||
[netframework_clrremoting](docs/collector.netframework_clrremoting.md) | .NET Framework Remoting metrics |
|
||||
[netframework_clrsecurity](docs/collector.netframework_clrsecurity.md) | .NET Framework Security Check metrics |
|
||||
[netframework](docs/collector.netframework.md) | .NET Framework metrics |
|
||||
[net](docs/collector.net.md) | Network interface I/O | ✓
|
||||
[os](docs/collector.os.md) | OS metrics (memory, processes, users) | ✓
|
||||
[pagefile](docs/collector.pagefile.md) | pagefile metrics |
|
||||
[perfdata](docs/collector.perfdata.md) | Custom perfdata metrics |
|
||||
[physical_disk](docs/collector.physical_disk.md) | physical disk metrics | ✓
|
||||
[printer](docs/collector.printer.md) | Printer metrics |
|
||||
[printer](docs/collector.printer.md) | Printer metrics |
|
||||
[process](docs/collector.process.md) | Per-process metrics |
|
||||
[remote_fx](docs/collector.remote_fx.md) | RemoteFX protocol (RDP) metrics |
|
||||
[scheduled_task](docs/collector.scheduled_task.md) | Scheduled Tasks metrics |
|
||||
@@ -52,12 +54,12 @@ Name | Description | Enabled by default
|
||||
[smtp](docs/collector.smtp.md) | IIS SMTP Server |
|
||||
[system](docs/collector.system.md) | System calls | ✓
|
||||
[tcp](docs/collector.tcp.md) | TCP connections |
|
||||
[teradici_pcoip](docs/collector.teradici_pcoip.md) | [Teradici PCoIP](https://www.teradici.com/web-help/pcoip_wmi_specs/) session metrics |
|
||||
[time](docs/collector.time.md) | Windows Time Service |
|
||||
[thermalzone](docs/collector.thermalzone.md) | Thermal information
|
||||
[terminal_services](docs/collector.terminal_services.md) | Terminal services (RDS)
|
||||
[textfile](docs/collector.textfile.md) | Read prometheus metrics from a text file |
|
||||
[vmware_blast](docs/collector.vmware_blast.md) | VMware Blast session metrics |
|
||||
[thermalzone](docs/collector.thermalzone.md) | Thermal information |
|
||||
[time](docs/collector.time.md) | Windows Time Service |
|
||||
[udp](docs/collector.udp.md) | UDP connections |
|
||||
[update](docs/collector.update.md) | Windows Update Service |
|
||||
[vmware](docs/collector.vmware.md) | Performance counters installed by the Vmware Guest agent |
|
||||
|
||||
See the linked documentation on each collector for more information on reported metrics, configuration settings and usage examples.
|
||||
@@ -81,17 +83,18 @@ This can be useful for having different Prometheus servers collect specific metr
|
||||
|
||||
windows_exporter accepts flags to configure certain behaviours. The ones configuring the global behaviour of the exporter are listed below, while collector-specific ones are documented in the respective collector documentation above.
|
||||
|
||||
| Flag | Description | Default value |
|
||||
|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
||||
| `--web.listen-address` | host:port for exporter. | `:9182` |
|
||||
| `--telemetry.path` | URL path for surfacing collected metrics. | `/metrics` |
|
||||
| `--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5` |
|
||||
| `--collectors.enabled` | Comma-separated list of collectors to use. Use `[defaults]` as a placeholder which gets expanded containing all the collectors enabled by default." | `[defaults]` |
|
||||
| `--collectors.print` | If true, print available collectors and exit. | |
|
||||
| `--scrape.timeout-margin` | Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads. | `0.5` |
|
||||
| `--web.config.file` | A [web config][web_config] for setting up TLS and Auth | None |
|
||||
| `--config.file` | [Using a config file](#using-a-configuration-file) from path or URL | None |
|
||||
| `--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false |
|
||||
| Flag | Description | Default value |
|
||||
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
||||
| `--web.listen-address` | host:port for exporter. | `:9182` |
|
||||
| `--telemetry.path` | URL path for surfacing collected metrics. | `/metrics` |
|
||||
| `--telemetry.max-requests` | Maximum number of concurrent requests. 0 to disable. | `5` |
|
||||
| `--collectors.enabled` | Comma-separated list of collectors to use. Use `[defaults]` as a placeholder which gets expanded containing all the collectors enabled by default." | `[defaults]` |
|
||||
| `--collectors.print` | If true, print available collectors and exit. | |
|
||||
| `--scrape.timeout-margin` | Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads. | `0.5` |
|
||||
| `--web.config.file` | A [web config][web_config] for setting up TLS and Auth | None |
|
||||
| `--config.file` | [Using a config file](#using-a-configuration-file) from path or URL | None |
|
||||
| `--config.file.insecure-skip-verify` | Skip TLS when loading config file from URL | false |
|
||||
| `--log.file` | Output file of log messages. One of [stdout, stderr, eventlog, \<path to log file>]<br>**NOTE:** The MSI installer will add a default argument to the installed service setting this to eventlog | stderr |
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -99,9 +102,9 @@ The latest release can be downloaded from the [releases page](https://github.com
|
||||
|
||||
Each release provides a .msi installer. The installer will setup the windows_exporter as a Windows service, as well as create an exception in the Windows Firewall.
|
||||
|
||||
If the installer is run without any parameters, the exporter will run with default settings for enabled collectors, ports, etc.
|
||||
If the installer is run without any parameters, the exporter will run with default settings for enabled collectors, ports, etc.
|
||||
|
||||
The installer provides a configuration file to customize the exporter.
|
||||
The installer provides a configuration file to customize the exporter.
|
||||
|
||||
The configuration file
|
||||
* is located in the same directory as the exporter executable.
|
||||
@@ -163,7 +166,7 @@ msiexec /i <path-to-msi-file> ENABLED_COLLECTORS=os,service --% EXTRA_FLAGS="--c
|
||||
|
||||
## Docker Implementation
|
||||
|
||||
The windows_exporter can be run as a Docker container. The Docker image is available on
|
||||
The windows_exporter can be run as a Docker container. The Docker image is available on
|
||||
|
||||
* [Docker Hub](https://hub.docker.com/r/prometheuscommunity/windows-exporter): `docker.io/prometheuscommunity/windows-exporter`
|
||||
* [GitHub Container Registry](https://github.com/prometheus-community/windows_exporter/pkgs/container/windows-exporter): `ghcr.io/prometheus-community/windows-exporter`
|
||||
@@ -200,7 +203,7 @@ The prometheus metrics will be exposed on [localhost:9182](http://localhost:9182
|
||||
|
||||
### Enable only service collector and specify a custom query
|
||||
|
||||
.\windows_exporter.exe --collectors.enabled "service" --collector.service.services-where "Name='windows_exporter'"
|
||||
.\windows_exporter.exe --collectors.enabled "service" --collector.service.include="windows_exporter"
|
||||
|
||||
### Enable only process collector and specify a custom query
|
||||
|
||||
@@ -229,7 +232,7 @@ collectors:
|
||||
enabled: cpu,net,service
|
||||
collector:
|
||||
service:
|
||||
services-where: "Name='windows_exporter'"
|
||||
include: windows_exporter
|
||||
log:
|
||||
level: warn
|
||||
```
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# example configuration file for windows_exporter
|
||||
|
||||
collectors:
|
||||
enabled: cpu,cpu_info,exchange,iis,logical_disk,logon,memory,net,os,process,remote_fx,service,system,tcp,time,terminal_services,textfile
|
||||
collector:
|
||||
service:
|
||||
services-where: "Name='windows_exporter'"
|
||||
include: "windows_exporter"
|
||||
log:
|
||||
level: warn
|
||||
level: warn
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
{{ template "head" . }}
|
||||
|
||||
{{ template "prom_content_head" . }}
|
||||
<h1>Node Overview - {{ reReplaceAll "(.*?://)([^:/]+?)(:\\d+)?/.*" "$2" .Params.instance }}</h1>
|
||||
|
||||
<h3>CPU Usage</h3>
|
||||
<div id="cpuGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#cpuGraph"),
|
||||
expr: "sum by (mode)(irate(windows_cpu_time_total{job='node',instance='{{ .Params.instance }}',mode!='idle'}[5m]))",
|
||||
renderer: 'area',
|
||||
max: {{ with printf "count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance | query }}{{ . | first | value }}{{ else}}undefined{{end}},
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yTitle: 'Cores'
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Network Utilization</h3>
|
||||
<div id="networkioGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#networkioGraph"),
|
||||
expr: [
|
||||
"irate(windows_net_bytes_sent_total{job='node',instance='{{ .Params.instance }}',nic!~'^isatap_ec2_internal'}[5m])",
|
||||
"irate(windows_net_bytes_received_total{job='node',instance='{{ .Params.instance }}',nic!~'^isatap_ec2_internal'}[5m])",
|
||||
],
|
||||
min: 0,
|
||||
name: [ 'sent', 'received' ],
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yUnits: "B",
|
||||
yTitle: 'Network IO'
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Disk I/O Utilization</h3>
|
||||
<div id="diskioGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#diskioGraph"),
|
||||
expr: [
|
||||
"100 - irate(windows_logical_disk_idle_seconds_total{job='node',instance='{{ .Params.instance }}',volume!~'^HarddiskVolume.*$'}[5m]) * 100",
|
||||
],
|
||||
min: 0,
|
||||
name: '[[ volume ]]',
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yUnits: "%",
|
||||
yTitle: 'Disk I/O Utilization'
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Memory</h3>
|
||||
<div id="memoryGraph"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#memoryGraph"),
|
||||
renderer: 'area',
|
||||
expr: [
|
||||
"windows_cs_physical_memory_bytes{job='node',instance='{{ .Params.instance }}'}",
|
||||
"windows_os_physical_memory_free_bytes{job='node',instance='{{ .Params.instance }}'}",
|
||||
"windows_cs_physical_memory__bytes{job='node',instance='{{ .Params.instance }}'} - windows_os_physical_memory_free_bytes{job='node',instance='{{.Params.instance}}'}",
|
||||
"windows_os_virtual_memory_bytes{job='node',instance='{{ .Params.instance }}'}",
|
||||
],
|
||||
name: ["Physical", "Free", "Used", "Virtual"],
|
||||
min: 0,
|
||||
yUnits: "B",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize1024,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize1024,
|
||||
yTitle: 'Memory'
|
||||
})
|
||||
</script>
|
||||
|
||||
{{ template "prom_right_table_head" }}
|
||||
<tr><th colspan="2">Overview</th></tr>
|
||||
<tr>
|
||||
<td>User CPU</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "sum(irate(windows_cpu_time_total{job='node',instance='%s',mode='user'}[5m])) * 100 / count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance .Params.instance) "%" "printf.1f") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Privileged CPU</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "sum(irate(windows_cpu_time_total{job='node',instance='%s',mode='privileged'}[5m])) * 100 / count(count by (cpu)(windows_cpu_time_total{job='node',instance='%s'}))" .Params.instance .Params.instance) "%" "printf.1f") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory Total</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "windows_cs_physical_memory_bytes{job='node',instance='%s'}" .Params.instance) "B" "humanize1024") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory Free</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "windows_os_physical_memory_free_bytes{job='node',instance='%s'}" .Params.instance) "B" "humanize1024") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">Network</th>
|
||||
</tr>
|
||||
{{ range printf "windows_net_bytes_received_total{job='node',instance='%s',nic!='isatap_ec2_internal'}" .Params.instance | query | sortByLabel "nic" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.nic }} Received</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_net_bytes_received_total{job='node',instance='%s',nic='%s'}[5m])" .Labels.instance .Labels.nic) "B/s" "humanize") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ .Labels.nic }} Transmitted</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_net_bytes_sent_total{job='node',instance='%s',nic='%s'}[5m])" .Labels.instance .Labels.nic) "B/s" "humanize") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">Disks</th>
|
||||
</tr>
|
||||
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.volume }} Utilization</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "100 - irate(windows_logical_disk_idle_seconds_total{job='node',instance='%s',volume='%s'}[5m]) * 100" .Labels.instance .Labels.volume) "%" "printf.1f") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.volume }} Throughput</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "irate(windows_logical_disk_read_bytes_total{job='node',instance='%s',volume='%s'}[5m]) + irate(windows_logical_disk_write_bytes_total{job='node',instance='%s',volume='%s'}[5m])" .Labels.instance .Labels.volume .Labels.instance .Labels.volume) "B/s" "humanize") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
<tr>
|
||||
<th colspan="2">Filesystem Fullness</th>
|
||||
</tr>
|
||||
{{ define "roughlyNearZero" }}
|
||||
{{ if gt .1 . }}~0{{ else }}{{ printf "%.1f" . }}{{ end }}
|
||||
{{ end }}
|
||||
{{ range printf "windows_logical_disk_size_bytes{job='node',instance='%s',volume!~'^HarddiskVolume.*$'}" .Params.instance | query | sortByLabel "volume" }}
|
||||
<tr>
|
||||
<td>{{ .Labels.volume }}</td>
|
||||
<td>{{ template "prom_query_drilldown" (args (printf "100 - windows_logical_disk_free_bytes{job='node',instance='%s',volume='%s'} / windows_logical_disk_size_bytes{job='node'} * 100" .Labels.instance .Labels.volume) "%" "roughlyNearZero") }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tr>
|
||||
{{ template "prom_right_table_tail" }}
|
||||
|
||||
{{ template "prom_content_tail" . }}
|
||||
|
||||
{{ template "tail" }}
|
||||
@@ -25,14 +25,7 @@ This directory contains documentation of the collectors in the windows_exporter,
|
||||
- [`msmq`](collector.msmq.md)
|
||||
- [`mssql`](collector.mssql.md)
|
||||
- [`net`](collector.net.md)
|
||||
- [`netframework_clrexceptions`](collector.netframework_clrexceptions.md)
|
||||
- [`netframework_clrinterop`](collector.netframework_clrinterop.md)
|
||||
- [`netframework_clrjit`](collector.netframework_clrjit.md)
|
||||
- [`netframework_clrloading`](collector.netframework_clrloading.md)
|
||||
- [`netframework_clrlocksandthreads`](collector.netframework_clrlocksandthreads.md)
|
||||
- [`netframework_clrmemory`](collector.netframework_clrmemory.md)
|
||||
- [`netframework_clrremoting`](collector.netframework_clrremoting.md)
|
||||
- [`netframework_clrsecurity`](collector.netframework_clrsecurity.md)
|
||||
- [`netframework`](collector.netframework.md)
|
||||
- [`nps`](collector.nps.md)
|
||||
- [`os`](collector.os.md)
|
||||
- [`physical_disk`](collector.physical_disk.md)
|
||||
@@ -44,10 +37,10 @@ This directory contains documentation of the collectors in the windows_exporter,
|
||||
- [`smtp`](collector.smtp.md)
|
||||
- [`system`](collector.system.md)
|
||||
- [`tcp`](collector.tcp.md)
|
||||
- [`teradici_pcoip`](collector.teradici_pcoip.md)
|
||||
- [`terminal_services`](collector.terminal_services.md)
|
||||
- [`textfile`](collector.textfile.md)
|
||||
- [`thermalzone`](collector.thermalzone.md)
|
||||
- [`time`](collector.time.md)
|
||||
- [`udp`](collector.udp.md)
|
||||
- [`update`](collector.update.md)
|
||||
- [`vmware`](collector.vmware.md)
|
||||
- [`vmware_blast`](collector.vmware_blast.md)
|
||||
|
||||
36
docs/collector.filetime.md
Normal file
36
docs/collector.filetime.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# filetime collector
|
||||
|
||||
The filetime collector exposes modified timestamps of files in the filesystem.
|
||||
|
||||
The collector
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `filetime`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collectors.filetime.file-patterns`
|
||||
Comma-separated list of file patterns. Each pattern is a glob pattern that can contain `*`, `?`, and `**` (recursive).
|
||||
See https://github.com/bmatcuk/doublestar#patterns for an extended description of the pattern syntax.
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_filetime_mtime_timestamp_seconds` | File modification time | gauge | `file`
|
||||
|
||||
### Example metric
|
||||
|
||||
```
|
||||
# HELP windows_filetime_mtime_timestamp_seconds File modification time
|
||||
# TYPE windows_filetime_mtime_timestamp_seconds gauge
|
||||
windows_filetime_mtime_timestamp_seconds{file="C:\\Users\\admin\\Desktop\\Dashboard.lnk"} 1.726434517e+09
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -2,13 +2,11 @@
|
||||
|
||||
The logon collector exposes metrics detailing the active user logon sessions.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `logon`
|
||||
Classes | [`Win32_LogonSession`](https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-logonsession)
|
||||
Enabled by default? | No
|
||||
|
||||
> :warning: **On some deployments, this collector seems to have some memory/timeout issues**: See [#583](https://github.com/prometheus-community/windows_exporter/issues/583)
|
||||
| | |
|
||||
|---------------------|-----------|
|
||||
| Metric name prefix | `logon` |
|
||||
| Source | Win32 API |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
@@ -16,21 +14,65 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_logon_logon_type` | Number of active user logon sessions | gauge | status
|
||||
| Name | Description | Type | Labels |
|
||||
|-------------------------------------------|--------------------------------------------|-------|------------------------------------|
|
||||
| `windows_logon_session_logon_timestamp_seconds` | timestamp of the logon session in seconds. | gauge | `domain`, `id`, `type`, `username` |
|
||||
|
||||
### Example metric
|
||||
Query the total number of interactive logon sessions
|
||||
```
|
||||
windows_logon_logon_type{status="interactive"}
|
||||
# HELP windows_logon_session_logon_timestamp_seconds timestamp of the logon session in seconds.
|
||||
# TYPE windows_logon_session_logon_timestamp_seconds gauge
|
||||
windows_logon_session_logon_timestamp_seconds{domain="",id="0x0:0x8c54",type="System",username=""} 1.72876928e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x991a",type="Interactive",username="UMFD-1"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x9933",type="Interactive",username="UMFD-0"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x994a",type="Interactive",username="UMFD-0"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0x999d",type="Interactive",username="UMFD-1"} 1.728769282e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0xbf25a",type="Interactive",username="UMFD-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Font Driver Host",id="0x0:0xbf290",type="Interactive",username="UMFD-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x130241",type="Network",username="vm-jok-dev$"} 1.728769625e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x24f7c9",type="Network",username="vm-jok-dev$"} 1.728770121e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x276846",type="Network",username="vm-jok-dev$"} 1.728770195e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x3e4",type="Service",username="vm-jok-dev$"} 1.728769283e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x3e7",type="System",username="vm-jok-dev$"} 1.728769279e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x71d0f",type="Network",username="vm-jok-dev$"} 1.728769324e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x720a3",type="Network",username="vm-jok-dev$"} 1.728769324e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x725cb",type="Network",username="vm-jok-dev$"} 1.728769324e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0x753d8",type="Network",username="vm-jok-dev$"} 1.728769325e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xa3913",type="Network",username="vm-jok-dev$"} 1.728769385e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xbe7f2",type="Network",username="jok"} 1.728769531e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="JKROEPKE",id="0x0:0xc76c4",type="RemoteInteractive",username="jok"} 1.728769533e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT AUTHORITY",id="0x0:0x3e3",type="Service",username="IUSR"} 1.728769295e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT AUTHORITY",id="0x0:0x3e5",type="Service",username="LOCAL SERVICE"} 1.728769283e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT Service",id="0x0:0xae4c7",type="Service",username="MSSQLSERVER"} 1.728769425e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="NT Service",id="0x0:0xb42f1",type="Service",username="SQLTELEMETRY"} 1.728769431e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xbfbac",type="Interactive",username="DWM-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xbfc72",type="Interactive",username="DWM-2"} 1.728769532e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xdedd",type="Interactive",username="DWM-1"} 1.728769283e+09
|
||||
windows_logon_session_logon_timestamp_seconds{domain="Window Manager",id="0x0:0xdefd",type="Interactive",username="DWM-1"} 1.728769283e+09
|
||||
```
|
||||
|
||||
### Possible values for `type`
|
||||
|
||||
- System
|
||||
- Interactive
|
||||
- Network
|
||||
- Batch
|
||||
- Service
|
||||
- Proxy
|
||||
- Unlock
|
||||
- NetworkCleartext
|
||||
- NewCredentials
|
||||
- RemoteInteractive
|
||||
- CachedInteractive
|
||||
- CachedRemoteInteractive
|
||||
- CachedUnlock
|
||||
|
||||
## Useful queries
|
||||
Query the total number of local and remote (I.E. Terminal Services) interactive sessions.
|
||||
```
|
||||
windows_logon_logon_type{status=~"interactive|remote_interactive"}
|
||||
count(windows_logon_logon_type{type=~"Interactive|RemoteInteractive"}) by (type)
|
||||
```
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
_This collector doesn’t yet have alerting examples, we would appreciate your help adding them!_
|
||||
|
||||
113
docs/collector.netframework.md
Normal file
113
docs/collector.netframework.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# netframework collector
|
||||
|
||||
The netframework collector exposes metrics about dotnet framework.
|
||||
|
||||
| | |
|
||||
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **Metric name prefix** | `netframework_clrexceptions` |
|
||||
| **Classes** | `Win32_PerfRawData_NETFramework_NETCLRExceptions`, `Win32_PerfRawData_NETFramework_NETCLRInterop`, `Win32_PerfRawData_NETFramework_NETCLRJit`, `Win32_PerfRawData_NETFramework_NETCLRLoading`, `Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads`, `Win32_PerfRawData_NETFramework_NETCLRMemory`, `Win32_PerfRawData_NETFramework_NETCLRRemoting`, `Win32_PerfRawData_NETFramework_NETCLRSecurity` |
|
||||
| **Enabled by default?** | No |
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
### CLR Exceptions
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrexceptions_exceptions_thrown_total` | Displays the total number of exceptions thrown since the application started. This includes both .NET exceptions and unmanaged exceptions that are converted into .NET exceptions. | counter | `process` |
|
||||
| `windows_netframework_clrexceptions_exceptions_filters_total` | Displays the total number of .NET exception filters executed. An exception filter evaluates regardless of whether an exception is handled. | counter | `process` |
|
||||
| `windows_netframework_clrexceptions_exceptions_finallys_total` | Displays the total number of finally blocks executed. Only the finally blocks executed for an exception are counted; finally blocks on normal code paths are not counted by this counter. | counter | `process` |
|
||||
| `windows_netframework_clrexceptions_throw_to_catch_depth_total` | Displays the total number of stack frames traversed, from the frame that threw the exception to the frame that handled the exception. | counter | `process` |
|
||||
|
||||
### CLR Interop
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrinterop_com_callable_wrappers_total` | Displays the current number of COM callable wrappers (CCWs). A CCW is a proxy for a managed object being referenced from an unmanaged COM client. | counter | `process` |
|
||||
| `windows_netframework_clrinterop_interop_marshalling_total` | Displays the total number of times arguments and return values have been marshaled from managed to unmanaged code, and vice versa, since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrinterop_interop_stubs_created_total` | Displays the current number of stubs created by the common language runtime. Stubs are responsible for marshaling arguments and return values from managed to unmanaged code, and vice versa, during a COM interop call or a platform invoke call. | counter | `process` |
|
||||
|
||||
### CLR JIT
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrjit_jit_methods_total` | Displays the total number of methods JIT-compiled since the application started. This counter does not include pre-JIT-compiled methods. | counter | `process` |
|
||||
| `windows_netframework_clrjit_jit_time_percent` | Displays the percentage of time spent in JIT compilation. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase occurs when a method and its dependencies are compiled. | gauge | `process` |
|
||||
| `windows_netframework_clrjit_jit_standard_failures_total` | Displays the peak number of methods the JIT compiler has failed to compile since the application started. This failure can occur if the MSIL cannot be verified or if there is an internal error in the JIT compiler. | counter | `process` |
|
||||
| `windows_netframework_clrjit_jit_il_bytes_total` | Displays the total number of Microsoft intermediate language (MSIL) bytes compiled by the just-in-time (JIT) compiler since the application started | counter | `process` |
|
||||
|
||||
### CLR Loading
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrloading_loader_heap_size_bytes` | Displays the current size, in bytes, of the memory committed by the class loader across all application domains. Committed memory is the physical space reserved in the disk paging file. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_appdomains_loaded_current` | Displays the current number of application domains loaded in this application. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_assemblies_loaded_current` | Displays the current number of assemblies loaded across all application domains in the currently running application. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_classes_loaded_current` | Displays the current number of classes loaded in all assemblies. | gauge | `process` |
|
||||
| `windows_netframework_clrloading_appdomains_loaded_total` | Displays the peak number of application domains loaded since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrloading_appdomains_unloaded_total` | Displays the total number of application domains unloaded since the application started. If an application domain is loaded and unloaded multiple times, this counter increments each time the application domain is unloaded. | counter | `process` |
|
||||
| `windows_netframework_clrloading_assemblies_loaded_total` | Displays the total number of assemblies loaded since the application started. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | counter | `process` |
|
||||
| `windows_netframework_clrloading_classes_loaded_total` | Displays the cumulative number of classes loaded in all assemblies since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrloading_class_load_failures_total` | Displays the peak number of classes that have failed to load since the application started. | counter | `process` |
|
||||
|
||||
### CLR Locks and Threads
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrlocksandthreads_current_queue_length` | Displays the total number of threads that are currently waiting to acquire a managed lock in the application. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_current_logical_threads` | Displays the number of current managed thread objects in the application. This counter maintains the count of both running and stopped threads. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_physical_threads_current` | Displays the number of native operating system threads created and owned by the common language runtime to act as underlying threads for managed thread objects. This counter's value does not include the threads used by the runtime in its internal operations; it is a subset of the threads in the operating system process. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_recognized_threads_current` | Displays the number of threads that are currently recognized by the runtime. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | gauge | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_recognized_threads_total` | Displays the total number of threads that have been recognized by the runtime since the application started. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | counter | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_queue_length_total` | Displays the total number of threads that waited to acquire a managed lock since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrlocksandthreads_contentions_total` | Displays the total number of times that threads in the runtime have attempted to acquire a managed lock unsuccessfully. | counter | `process` |
|
||||
|
||||
### CLR Memory
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrmemory_allocated_bytes_total` | Displays the total number of bytes allocated on the garbage collection heap. | counter | `process` |
|
||||
| `windows_netframework_clrmemory_finalization_survivors` | Displays the number of garbage-collected objects that survive a collection because they are waiting to be finalized. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_heap_size_bytes` | Displays the maximum bytes that can be allocated; it does not indicate the current number of bytes allocated. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_promoted_bytes` | Displays the bytes that were promoted from the generation to the next one during the last GC. Memory is promoted when it survives a garbage collection. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_number_gc_handles` | Displays the current number of garbage collection handles in use. Garbage collection handles are handles to resources external to the common language runtime and the managed environment. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_collections_total` | Displays the number of times the generation objects are garbage collected since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrmemory_induced_gc_total` | Displays the peak number of times garbage collection was performed because of an explicit call to GC.Collect. | counter | `process` |
|
||||
| `windows_netframework_clrmemory_number_pinned_objects` | Displays the number of pinned objects encountered in the last garbage collection. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_number_sink_blocksinuse` | Displays the current number of synchronization blocks in use. Synchronization blocks are per-object data structures allocated for storing synchronization information. They hold weak references to managed objects and must be scanned by the garbage collector. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_committed_bytes` | Displays the amount of virtual memory, in bytes, currently committed by the garbage collector. Committed memory is the physical memory for which space has been reserved in the disk paging file. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_reserved_bytes` | Displays the amount of virtual memory, in bytes, currently reserved by the garbage collector. Reserved memory is the virtual memory space reserved for the application when no disk or main memory pages have been used. | gauge | `process` |
|
||||
| `windows_netframework_clrmemory_gc_time_percent` | Displays the percentage of time that was spent performing a garbage collection in the last sample. | gauge | `process` |
|
||||
|
||||
### CLR Remoting
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrremoting_channels_total` | Displays the total number of remoting channels registered across all application domains since application started. | counter | `process` |
|
||||
| `windows_netframework_clrremoting_context_bound_classes_loaded` | Displays the current number of context-bound classes that are loaded. | gauge | `process` |
|
||||
| `windows_netframework_clrremoting_context_bound_objects_total` | Displays the total number of context-bound objects allocated. | counter | `process` |
|
||||
| `windows_netframework_clrremoting_context_proxies_total` | Displays the total number of remoting proxy objects in this process since it started. | counter | `process` |
|
||||
| `windows_netframework_clrremoting_contexts` | Displays the current number of remoting contexts in the application. | gauge | `process` |
|
||||
| `windows_netframework_clrremoting_remote_calls_total` | Displays the total number of remote procedure calls invoked since the application started. | counter | `process` |
|
||||
|
||||
### CLR Security
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|---------|-----------|
|
||||
| `windows_netframework_clrsecurity_link_time_checks_total` | Displays the total number of link-time code access security checks since the application started. | counter | `process` |
|
||||
| `windows_netframework_clrsecurity_rt_checks_time_percent` | Displays the percentage of time spent performing runtime code access security checks in the last sample. | gauge | `process` |
|
||||
| `windows_netframework_clrsecurity_stack_walk_depth` | Displays the depth of the stack during that last runtime code access security check. | gauge | `process` |
|
||||
| `windows_netframework_clrsecurity_runtime_checks_total` | Displays the total number of runtime code access security checks performed since the application started. | counter | `process` |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,31 +0,0 @@
|
||||
# netframework_clrexceptions collector
|
||||
|
||||
The netframework_clrexceptions collector exposes metrics about CLR exceptions in the dotnet framework.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrexceptions`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRExceptions`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrexceptions_exceptions_thrown_total` | Displays the total number of exceptions thrown since the application started. This includes both .NET exceptions and unmanaged exceptions that are converted into .NET exceptions. | counter | `process`
|
||||
`windows_netframework_clrexceptions_exceptions_filters_total` | Displays the total number of .NET exception filters executed. An exception filter evaluates regardless of whether an exception is handled. | counter | `process`
|
||||
`windows_netframework_clrexceptions_exceptions_finallys_total` | Displays the total number of finally blocks executed. Only the finally blocks executed for an exception are counted; finally blocks on normal code paths are not counted by this counter. | counter | `process`
|
||||
`windows_netframework_clrexceptions_throw_to_catch_depth_total` | Displays the total number of stack frames traversed, from the frame that threw the exception to the frame that handled the exception. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,30 +0,0 @@
|
||||
# netframework_clrinterop collector
|
||||
|
||||
The netframework_clrinterop collector exposes metrics about interop between the dotnet framework and outside components.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrinterop`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRInterop`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrinterop_com_callable_wrappers_total` | Displays the current number of COM callable wrappers (CCWs). A CCW is a proxy for a managed object being referenced from an unmanaged COM client. | counter | `process`
|
||||
`windows_netframework_clrinterop_interop_marshalling_total` | Displays the total number of times arguments and return values have been marshaled from managed to unmanaged code, and vice versa, since the application started. | counter | `process`
|
||||
`windows_netframework_clrinterop_interop_stubs_created_total` | Displays the current number of stubs created by the common language runtime. Stubs are responsible for marshaling arguments and return values from managed to unmanaged code, and vice versa, during a COM interop call or a platform invoke call. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,31 +0,0 @@
|
||||
# netframework_clrjit collector
|
||||
|
||||
The netframework_clrjit collector exposes metrics about the dotnet Just-in-Time compiler.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrjit`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRJit`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrjit_jit_methods_total` | Displays the total number of methods JIT-compiled since the application started. This counter does not include pre-JIT-compiled methods. | counter | `process`
|
||||
`windows_netframework_clrjit_jit_time_percent` | Displays the percentage of time spent in JIT compilation. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase occurs when a method and its dependencies are compiled. | gauge | `process`
|
||||
`windows_netframework_clrjit_jit_standard_failures_total` | Displays the peak number of methods the JIT compiler has failed to compile since the application started. This failure can occur if the MSIL cannot be verified or if there is an internal error in the JIT compiler. | counter | `process`
|
||||
`windows_netframework_clrjit_jit_il_bytes_total` | Displays the total number of Microsoft intermediate language (MSIL) bytes compiled by the just-in-time (JIT) compiler since the application started | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,36 +0,0 @@
|
||||
# netframework_clrloading collector
|
||||
|
||||
The netframework_clrloading collector exposes metrics about the dotnet loader.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrloading`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRLoading`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrloading_loader_heap_size_bytes` | Displays the current size, in bytes, of the memory committed by the class loader across all application domains. Committed memory is the physical space reserved in the disk paging file. | gauge | `process`
|
||||
`windows_netframework_clrloading_appdomains_loaded_current` | Displays the current number of application domains loaded in this application. | gauge | `process`
|
||||
`windows_netframework_clrloading_assemblies_loaded_current` | Displays the current number of assemblies loaded across all application domains in the currently running application. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | gauge | `process`
|
||||
`windows_netframework_clrloading_classes_loaded_current` | Displays the current number of classes loaded in all assemblies. | gauge | `process`
|
||||
`windows_netframework_clrloading_appdomains_loaded_total` | Displays the peak number of application domains loaded since the application started. | counter | `process`
|
||||
`windows_netframework_clrloading_appdomains_unloaded_total` | Displays the total number of application domains unloaded since the application started. If an application domain is loaded and unloaded multiple times, this counter increments each time the application domain is unloaded. | counter | `process`
|
||||
`windows_netframework_clrloading_assemblies_loaded_total` | Displays the total number of assemblies loaded since the application started. If the assembly is loaded as domain-neutral from multiple application domains, this counter is incremented only once. | counter | `process`
|
||||
`windows_netframework_clrloading_classes_loaded_total` | Displays the cumulative number of classes loaded in all assemblies since the application started. | counter | `process`
|
||||
`windows_netframework_clrloading_class_load_failures_total` | Displays the peak number of classes that have failed to load since the application started. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,34 +0,0 @@
|
||||
# netframework_clrlocksandthreads collector
|
||||
|
||||
The netframework_clrlocksandthreads collector exposes metrics about locks and threads in dotnet applications.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrlocksandthreads`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrlocksandthreads_current_queue_length` | Displays the total number of threads that are currently waiting to acquire a managed lock in the application. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_current_logical_threads` | Displays the number of current managed thread objects in the application. This counter maintains the count of both running and stopped threads. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_physical_threads_current` | Displays the number of native operating system threads created and owned by the common language runtime to act as underlying threads for managed thread objects. This counter's value does not include the threads used by the runtime in its internal operations; it is a subset of the threads in the operating system process. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_recognized_threads_current` | Displays the number of threads that are currently recognized by the runtime. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | gauge | `process`
|
||||
`windows_netframework_clrlocksandthreads_recognized_threads_total` | Displays the total number of threads that have been recognized by the runtime since the application started. These threads are associated with a corresponding managed thread object. The runtime does not create these threads, but they have run inside the runtime at least once. | counter | `process`
|
||||
`windows_netframework_clrlocksandthreads_queue_length_total` | Displays the total number of threads that waited to acquire a managed lock since the application started. | counter | `process`
|
||||
`windows_netframework_clrlocksandthreads_contentions_total` | Displays the total number of times that threads in the runtime have attempted to acquire a managed lock unsuccessfully. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,39 +0,0 @@
|
||||
# netframework_clrmemory collector
|
||||
|
||||
The netframework_clrmemory collector exposes metrics about memory in dotnet applications.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrmemory`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRMemory`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrmemory_allocated_bytes_total` | Displays the total number of bytes allocated on the garbage collection heap. | counter | `process`
|
||||
`windows_netframework_clrmemory_finalization_survivors` | Displays the number of garbage-collected objects that survive a collection because they are waiting to be finalized. | gauge | `process`
|
||||
`windows_netframework_clrmemory_heap_size_bytes` | Displays the maximum bytes that can be allocated; it does not indicate the current number of bytes allocated. | gauge | `process`
|
||||
`windows_netframework_clrmemory_promoted_bytes` | Displays the bytes that were promoted from the generation to the next one during the last GC. Memory is promoted when it survives a garbage collection. | gauge | `process`
|
||||
`windows_netframework_clrmemory_number_gc_handles` | Displays the current number of garbage collection handles in use. Garbage collection handles are handles to resources external to the common language runtime and the managed environment. | gauge | `process`
|
||||
`windows_netframework_clrmemory_collections_total` | Displays the number of times the generation objects are garbage collected since the application started. | counter | `process`
|
||||
`windows_netframework_clrmemory_induced_gc_total` | Displays the peak number of times garbage collection was performed because of an explicit call to GC.Collect. | counter | `process`
|
||||
`windows_netframework_clrmemory_number_pinned_objects` | Displays the number of pinned objects encountered in the last garbage collection. | gauge | `process`
|
||||
`windows_netframework_clrmemory_number_sink_blocksinuse` | Displays the current number of synchronization blocks in use. Synchronization blocks are per-object data structures allocated for storing synchronization information. They hold weak references to managed objects and must be scanned by the garbage collector. | gauge | `process`
|
||||
`windows_netframework_clrmemory_committed_bytes` | Displays the amount of virtual memory, in bytes, currently committed by the garbage collector. Committed memory is the physical memory for which space has been reserved in the disk paging file. | gauge | `process`
|
||||
`windows_netframework_clrmemory_reserved_bytes` | Displays the amount of virtual memory, in bytes, currently reserved by the garbage collector. Reserved memory is the virtual memory space reserved for the application when no disk or main memory pages have been used. | gauge | `process`
|
||||
`windows_netframework_clrmemory_gc_time_percent` | Displays the percentage of time that was spent performing a garbage collection in the last sample. | gauge | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,33 +0,0 @@
|
||||
# netframework_clrremoting collector
|
||||
|
||||
The netframework_clrremoting collector exposes metrics about dotnet remoting.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrremoting`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRRemoting`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrremoting_channels_total` | Displays the total number of remoting channels registered across all application domains since application started. | counter | `process`
|
||||
`windows_netframework_clrremoting_context_bound_classes_loaded` | Displays the current number of context-bound classes that are loaded. | gauge | `process`
|
||||
`windows_netframework_clrremoting_context_bound_objects_total` | Displays the total number of context-bound objects allocated. | counter | `process`
|
||||
`windows_netframework_clrremoting_context_proxies_total` | Displays the total number of remoting proxy objects in this process since it started. | counter | `process`
|
||||
`windows_netframework_clrremoting_contexts` | Displays the current number of remoting contexts in the application. | gauge | `process`
|
||||
`windows_netframework_clrremoting_remote_calls_total` | Displays the total number of remote procedure calls invoked since the application started. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -1,31 +0,0 @@
|
||||
# netframework_clrsecurity collector
|
||||
|
||||
The netframework_clrsecurity collector exposes metrics about security checks in dotnet applications
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `netframework_clrsecurity`
|
||||
Classes | `Win32_PerfRawData_NETFramework_NETCLRSecurity`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_netframework_clrsecurity_link_time_checks_total` | Displays the total number of link-time code access security checks since the application started. | counter | `process`
|
||||
`windows_netframework_clrsecurity_rt_checks_time_percent` | Displays the percentage of time spent performing runtime code access security checks in the last sample. | gauge | `process`
|
||||
`windows_netframework_clrsecurity_stack_walk_depth` | Displays the depth of the stack during that last runtime code access security check. | gauge | `process`
|
||||
`windows_netframework_clrsecurity_runtime_checks_total` | Displays the total number of runtime code access security checks performed since the application started. | counter | `process`
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -14,13 +14,11 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|------------------------------------------------------------------------|
|
||||
| `windows_os_info` | Contains full product name & version in labels. Note that the `major_version` for Windows 11 is "10"; a build number greater than 22000 represents Windows 11. | gauge | `product`, `version`, `major_version`, `minor_version`, `build_number` |
|
||||
| `windows_os_paging_limit_bytes` | Total number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | None |
|
||||
| `windows_os_paging_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | None |
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|------------------------------------------------------------------------|
|
||||
| `windows_os_hostname` | Labelled system hostname information as provided by ComputerSystem.DNSHostName and ComputerSystem.Domain | gauge | `domain`, `fqdn`, `hostname` |
|
||||
| `windows_os_info` | Contains full product name & version in labels. Note that the `major_version` for Windows 11 is "10"; a build number greater than 22000 represents Windows 11. | gauge | `product`, `version`, `major_version`, `minor_version`, `build_number` |
|
||||
|
||||
|
||||
### Example metric
|
||||
|
||||
```
|
||||
@@ -36,4 +34,4 @@ windows_os_info{build_number="19045",major_version="10",minor_version="0",produc
|
||||
_This collector does not yet have useful queries, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
|
||||
38
docs/collector.pagefile.md
Normal file
38
docs/collector.pagefile.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# pagefile collector
|
||||
|
||||
The pagefile collector exposes metrics about the pagefile usage
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `pagefile`
|
||||
Classes | [`Win32_OperatingSystem`](https://msdn.microsoft.com/en-us/library/aa394239)
|
||||
Enabled by default? | Yes
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-------|--------|
|
||||
| `windows_pagefile_free_bytes` | Number of bytes that can be mapped into the operating system paging files without causing any other pages to be swapped out | gauge | `file` |
|
||||
| `windows_pagefile_limit_bytes` | Number of bytes that can be stored in the operating system paging files. 0 (zero) indicates that there are no paging files | gauge | `file` |
|
||||
|
||||
|
||||
### Example metric
|
||||
|
||||
```
|
||||
# HELP windows_pagefile_free_bytes OperatingSystem.FreeSpaceInPagingFiles
|
||||
# TYPE windows_pagefile_free_bytes gauge
|
||||
windows_pagefile_free_bytes{file="C:\\pagefile.sys"} 6.025797632e+09
|
||||
# HELP windows_pagefile_limit_bytes OperatingSystem.SizeStoredInPagingFiles
|
||||
# TYPE windows_pagefile_limit_bytes gauge
|
||||
windows_pagefile_limit_bytes{file="C:\\pagefile.sys"} 6.442450944e+09
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have useful queries, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -35,7 +35,7 @@ metrics.
|
||||
|
||||
Enables IIS process name queries. IIS process names are combined with their app pool name to form the `process` label.
|
||||
|
||||
Disabled by default, and can be enabled with `--collector.process.iis=true`.
|
||||
Disabled by default, and can be enabled with `--collector.process.iis`. NOTE: Just plain parameter without `true`.
|
||||
|
||||
|
||||
### Example
|
||||
@@ -44,7 +44,7 @@ Note that multiple processes with the same name will be disambiguated by
|
||||
Windows by adding a number suffix, such as `firefox#2`. Your [regexp](https://en.wikipedia.org/wiki/Regular_expression) must take
|
||||
these suffixes into consideration.
|
||||
|
||||
:warning: The regexp is case-sensitive, so `--collector.process.include="FIREFOX.*"` will **NOT** match a process named `firefox` .
|
||||
:warning: The regexp is case-sensitive, so `--collector.process.include="FIREFOX.*"` will **NOT** match a process named `firefox` .
|
||||
|
||||
To specify multiple names, use the pipe `|` character:
|
||||
```
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
# tcp collector
|
||||
|
||||
The tcp collector exposes metrics about the TCP/IPv4 network stack.
|
||||
The tcp collector exposes metrics about the TCP network stack.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `tcp`
|
||||
Data source | Perflib
|
||||
Classes | [`Win32_PerfRawData_Tcpip_TCPv4`](https://msdn.microsoft.com/en-us/library/aa394341(v=vs.85).aspx), Win32_PerfRawData_Tcpip_TCPv6
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
@@ -15,17 +14,18 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_tcp_connection_failures_total` | Number of times TCP connections have made a direct transition to the CLOSED state from the SYN-SENT state or the SYN-RCVD state, plus the number of times TCP connections have made a direct transition from the SYN-RCVD state to the LISTEN state | counter | af
|
||||
`windows_tcp_connections_active_total` | Number of times TCP connections have made a direct transition from the CLOSED state to the SYN-SENT state.| counter | af
|
||||
`windows_tcp_connections_established` | Number of TCP connections for which the current state is either ESTABLISHED or CLOSE-WAIT. | gauge | af
|
||||
`windows_tcp_connections_passive_total` | Number of times TCP connections have made a direct transition from the LISTEN state to the SYN-RCVD state. | counter | af
|
||||
`windows_tcp_connections_reset_total` | Connections Reset is the number of times TCP connections have made a direct transition to the CLOSED state from either the ESTABLISHED state or the CLOSE-WAIT state. | counter | af
|
||||
`windows_tcp_segments_total` | Total segments sent or received using the TCP protocol | counter | af
|
||||
`windows_tcp_segments_received_total` | Total segments received, including those received in error. This count includes segments received on currently established connections | counter | af
|
||||
`windows_tcp_segments_retransmitted_total` | Total segments retransmitted. That is, segments transmitted that contain one or more previously transmitted bytes | counter | af
|
||||
`windows_tcp_segments_sent_total` | Total segments sent, including those on current connections, but excluding those containing *only* retransmitted bytes | counter | af
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
|
||||
| `windows_tcp_connection_failures_total` | Number of times TCP connections have made a direct transition to the CLOSED state from the SYN-SENT state or the SYN-RCVD state, plus the number of times TCP connections have made a direct transition from the SYN-RCVD state to the LISTEN state | counter | af |
|
||||
| `windows_tcp_connections_active_total` | Number of times TCP connections have made a direct transition from the CLOSED state to the SYN-SENT state. | counter | af |
|
||||
| `windows_tcp_connections_established` | Number of TCP connections for which the current state is either ESTABLISHED or CLOSE-WAIT. | gauge | af |
|
||||
| `windows_tcp_connections_passive_total` | Number of times TCP connections have made a direct transition from the LISTEN state to the SYN-RCVD state. | counter | af |
|
||||
| `windows_tcp_connections_reset_total` | Connections Reset is the number of times TCP connections have made a direct transition to the CLOSED state from either the ESTABLISHED state or the CLOSE-WAIT state. | counter | af |
|
||||
| `windows_tcp_segments_total` | Total segments sent or received using the TCP protocol | counter | af |
|
||||
| `windows_tcp_segments_received_total` | Total segments received, including those received in error. This count includes segments received on currently established connections | counter | af |
|
||||
| `windows_tcp_segments_retransmitted_total` | Total segments retransmitted. That is, segments transmitted that contain one or more previously transmitted bytes | counter | af |
|
||||
| `windows_tcp_segments_sent_total` | Total segments sent, including those on current connections, but excluding those containing *only* retransmitted bytes | counter | af |
|
||||
| `windows_tcp_connections_state_count` | Number of TCP connections by state among: CLOSED, LISTENING, SYN_SENT, SYN_RECEIVED, ESTABLISHED, FIN_WAIT1, FIN_WAIT2, CLOSE_WAIT, CLOSING, LAST_ACK, TIME_WAIT, DELETE_TCB | gauge | af |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
# teradici_pcoip collector
|
||||
|
||||
The teradici_pcoip collector exposes metrics relating to Teradici PCoIP sessions
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `teradici_pcoip`
|
||||
Classes | `Win32_PerfRawData_TeradiciPerf_PCoIPSessionAudioStatistics`, `Win32_PerfRawData_TeradiciPerf_PCoIPSessionGeneralStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionImagingStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics`,`Win32_PerfRawData_TeradiciPerf_PCoIPSessionUsbStatistics`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_teradici_pcoip_audio_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_audio_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_audio_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_audio_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_audio_tx_bw_limit_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_packets_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_packets_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_rx_packets_lost_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_session_duration_seconds_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_tx_packets_lost_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_active_min_quality` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_apex2800_offload` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_decoder_capability_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_encoded_frames_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_megapixel_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_negative_acks_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_imaging_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_svga_devtap_frames_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_imaging_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_round_trip_latency_ms` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_bw_peak_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_packet_loss_percent` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_rx_packet_loss_percent_base` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_bw_active_limit_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_bw_limit_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_packet_loss_percent` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_tx_packet_loss_percent_base` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_usb_bytes_received_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_usb_bytes_sent_total` | _Not yet documented_ | counter | None
|
||||
`windows_teradici_pcoip_usb_rx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
`windows_teradici_pcoip_usb_tx_bw_kbit_persec` | _Not yet documented_ | gauge | None
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -6,7 +6,7 @@ The textfile collector exposes metrics from files written by other processes.
|
||||
-|-
|
||||
Metric name prefix | `textfile`
|
||||
Classes | None
|
||||
Enabled by default? | Yes
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
|
||||
@@ -5,15 +5,19 @@ If the Windows Time Service is stopped after collection has started, collector m
|
||||
|
||||
Please note the Time Service perflib counters are only available on [Windows Server 2016 or newer](https://docs.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-server-2016-improvements).
|
||||
|
||||
| | |
|
||||
|---------------------|---------|
|
||||
| Metric name prefix | `time` |
|
||||
| Data source | Perflib |
|
||||
| Enabled by default? | No |
|
||||
| | |
|
||||
|---------------------|--------|
|
||||
| Metric name prefix | `time` |
|
||||
| Data source | PDH |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
### `--collectors.time.enabled`
|
||||
Comma-separated list of collectors to use, for example: `--collectors.time.enabled=ntp,system_time`.
|
||||
Matching is case-sensitive.
|
||||
|
||||
|
||||
|
||||
## Metrics
|
||||
|
||||
|
||||
31
docs/collector.udp.md
Normal file
31
docs/collector.udp.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# udp collector
|
||||
|
||||
The udp collector exposes metrics about the UDP network stack.
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `udp`
|
||||
Data source | Perflib
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
|
||||
| `windows_udp_datagram_datagram_no_port_total` | Number of received UDP datagrams for which there was no application at the destination port | counter | af |
|
||||
| `windows_udp_datagram_received_errors_total` | Number of received UDP datagrams that could not be delivered for reasons other than the lack of an application at the destination port | counter | af |
|
||||
| `windows_udp_datagram_received_total` | Number of UDP datagrams segments received | counter | af |
|
||||
| `windows_udp_datagram_sent_total` | Number of UDP datagrams segments sent | counter | af |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
48
docs/collector.update.md
Normal file
48
docs/collector.update.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# update collector
|
||||
|
||||
The update collector exposes the Windows Update service metrics. Note that the Windows Update service (`wuauserv`) must be running, else metric collection will fail.
|
||||
|
||||
The Windows Update service is responsible for managing the installation of updates for the operating system and other Microsoft software. The service can be configured to automatically download and install updates, or to notify the user when updates are available.
|
||||
|
||||
|
||||
| | |
|
||||
|---------------------|------------------------|
|
||||
| Metric name prefix | `update` |
|
||||
| Data source | Windows Update service |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collector.updates.online`
|
||||
Whether to search for updates online. If set to `false`, the collector will only list updates that are already found by the Windows Update service.
|
||||
Set to `true` to search for updates online, which will take longer to complete.
|
||||
|
||||
### `--collector.updates.scrape-interval`
|
||||
Define the interval of scraping Windows Update information
|
||||
|
||||
## Metrics
|
||||
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------|-----------------------------------------------|-------|-------------------------------|
|
||||
| `windows_updates_pending_info` | Expose information single pending update item | gauge | `category`,`severity`,`title` |
|
||||
| `windows_updates_scrape_query_duration_seconds` | Duration of the last scrape query to the Windows Update API | gauge | |
|
||||
| `windows_updates_scrape_timestamp_seconds` | Timestamp of the last scrape | gauge | |
|
||||
|
||||
### Example metrics
|
||||
```
|
||||
# HELP windows_updates_pending Pending Windows Updates
|
||||
# TYPE windows_updates_pending gauge
|
||||
windows_updates_pending{category="Drivers",severity="",title="Intel Corporation - Bluetooth - 23.60.5.10"} 1
|
||||
# HELP windows_updates_scrape_query_duration_seconds Duration of the last scrape query to the Windows Update API
|
||||
# TYPE windows_updates_scrape_query_duration_seconds gauge
|
||||
windows_updates_scrape_query_duration_seconds 2.8161838
|
||||
# HELP windows_updates_scrape_timestamp_seconds Timestamp of the last scrape
|
||||
# TYPE windows_updates_scrape_timestamp_seconds gauge
|
||||
windows_updates_scrape_timestamp_seconds 1.727539734e+09
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
The vmware collector exposes metrics about a VMware guest VM
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `vmware`
|
||||
Classes | `Win32_PerfRawData_vmGuestLib_VMem`, `Win32_PerfRawData_vmGuestLib_VCPU`
|
||||
Enabled by default? | No
|
||||
| | |
|
||||
|---------------------|----------------------|
|
||||
| Metric name prefix | `vmware` |
|
||||
| Source | Performance counters |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
@@ -14,27 +14,27 @@ None
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_vmware_mem_active_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_ballooned_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_limit_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_mapped_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_overhead_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_reservation_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_shared_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_shared_saved_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_shares` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_swapped_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_target_size_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_mem_used_bytes` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_cpu_limit_mhz` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_cpu_reservation_mhz` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_cpu_shares` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_cpu_stolen_seconds_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_cpu_time_seconds_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_effective_vm_speed_mhz` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_host_processor_speed_mhz` | _Not yet documented_ | gauge | None
|
||||
| Name | Description | Type | Labels |
|
||||
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|
|
||||
| `windows_vmware_mem_active_bytes` | The estimated amount of memory the virtual machine is actively using. | gauge | None |
|
||||
| `windows_vmware_mem_ballooned_bytes` | The amount of memory that has been reclaimed from this virtual machine via the VMware Memory Balloon mechanism. | gauge | None |
|
||||
| `windows_vmware_mem_limit_bytes` | The maximum amount of memory that is allowed to the virtual machine. Assigning a Memory Limit ensures that this virtual machine never consumes more than a certain amount of the allowed memory. By limiting the amount of memory consumed, a portion of this shared resource is allowed to other virtual machines. | gauge | None |
|
||||
| `windows_vmware_mem_mapped_bytes` | The mapped memory size of this virtual machine. This is the current total amount of guest memory that is backed by physical memory. Note that this number may include pages of memory shared between multiple virtual machines and thus may be an overestimate of the amount of physical host memory consumed by this virtual machine. | gauge | None |
|
||||
| `windows_vmware_mem_overhead_bytes` | The amount of overhead memory associated with this virtual machine consumed on the host system. | gauge | None |
|
||||
| `windows_vmware_mem_reservation_bytes` | The minimum amount of memory that is guaranteed to the virtual machine. Assigning a Memory Reservation ensures that even as other virtual machines on the same host consume memory, there is still a certain minimum amount for this virtual machine. | gauge | None |
|
||||
| `windows_vmware_mem_shared_bytes` | The amount of physical memory associated with this virtual machine that is copy-on-write (COW) shared on the host. | gauge | None |
|
||||
| `windows_vmware_mem_shared_saved_bytes` | The estimated amount of physical memory on the host saved from copy-on-write (COW) shared guest physical memory. | gauge | None |
|
||||
| `windows_vmware_mem_shares` | The number of memory shares allocated to the virtual machine. | gauge | None |
|
||||
| `windows_vmware_mem_swapped_bytes` | The amount of memory associated with this virtual machine that has been swapped by ESX. | gauge | None |
|
||||
| `windows_vmware_mem_target_size_bytes` | Memory Target Size | gauge | None |
|
||||
| `windows_vmware_mem_used_bytes` | The estimated amount of physical host memory currently consumed for this virtual machine’s physical memory. | gauge | None |
|
||||
| `windows_vmware_cpu_limit_mhz` | The maximum processing power in MHz allowed to the virtual machine. Assigning a CPU Limit ensures that this virtual machine never consumes more than a certain amount of the available processor power. By limiting the amount of processing power consumed, a portion of the processing power becomes available to other virtual machines. | gauge | None |
|
||||
| `windows_vmware_cpu_reservation_mhz` | The minimum processing power in MHz available to the virtual machine. Assigning a CPU Reservation ensures that even as other virtual machines on the same host consume shared processing power, there is still a certain minimum amount for this virtual machine. | gauge | None |
|
||||
| `windows_vmware_cpu_shares` | The number of CPU shares allocated to the virtual machine. | gauge | None |
|
||||
| `windows_vmware_cpu_stolen_seconds_total` | The time that the VM was runnable but not scheduled to run | counter | None |
|
||||
| `windows_vmware_cpu_time_seconds_total` | Current load of the VM’s virtual processor | counter | None |
|
||||
| `windows_vmware_cpu_effective_vm_speed_mhz` | The effective speed of the VM’s virtual CPU | gauge | None |
|
||||
| `windows_vmware_host_processor_speed_mhz` | Host Processor speed | gauge | None |
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# vmware_blast collector
|
||||
|
||||
The vmware_blast collector exposes metrics relating to VMware Blast sessions
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `vmware_blast`
|
||||
Classes | `Win32_PerfRawData_Counters_VMwareBlastAudioCounters`,`Win32_PerfRawData_Counters_VMwareBlastCDRCounters`,`Win32_PerfRawData_Counters_VMwareBlastClipboardCounters`,`Win32_PerfRawData_Counters_VMwareBlastHTML5MMRCounters`,`Win32_PerfRawData_Counters_VMwareBlastImagingCounters`,`Win32_PerfRawData_Counters_VMwareBlastRTAVCounters`,`Win32_PerfRawData_Counters_VMwareBlastSerialPortandScannerCounters`,`Win32_PerfRawData_Counters_VMwareBlastSessionCounters`,`Win32_PerfRawData_Counters_VMwareBlastSkypeforBusinessControlCounters`,`Win32_PerfRawData_Counters_VMwareBlastThinPrintCounters`,`Win32_PerfRawData_Counters_VMwareBlastUSBCounters`,`Win32_PerfRawData_Counters_VMwareBlastWindowsMediaMMRCounters`
|
||||
Enabled by default? | No
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
|
||||
## Metrics
|
||||
|
||||
Some of these metrics may not be collected, depending on the installation options chosen when installing the Horizon agent
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_vmware_blast_audio_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_audio_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_audio_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_audio_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_cdr_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_clipboard_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_html5_mmr_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_dirty_frames_per_second` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_fbc_rate` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_frames_per_second` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_poll_rate` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_imaging_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_dirty_frames_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_fbc_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_frames_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_poll_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_imaging_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_rtav_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_serial_port_and_scanner_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_automatic_reconnect_count_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_received_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_received_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_transmitted_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_cumlative_transmitted_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_estimated_bandwidth_uplink` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_instantaneous_received_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_instantaneous_received_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_instantaneous_transmitted_bytes_over_tcp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_instantaneous_transmitted_bytes_over_udp_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_jitter_uplink` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_packet_loss_uplink` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_rtt` | _Not yet documented_ | gauge | None
|
||||
`windows_vmware_blast_session_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_session_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_skype_for_business_control_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_thinprint_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_usb_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_received_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_received_packets_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_transmitted_bytes_total` | _Not yet documented_ | counter | None
|
||||
`windows_vmware_blast_windows_media_mmr_transmitted_packets_total` | _Not yet documented_ | counter | None
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
## Alerting examples
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
@@ -4,7 +4,7 @@ collectors:
|
||||
enabled: cpu,cs,logical_disk,net,os,service,system
|
||||
collector:
|
||||
service:
|
||||
services-where: Name='windows_exporter'
|
||||
include: "windows_exporter"
|
||||
scheduled_task:
|
||||
include: /Microsoft/.+
|
||||
log:
|
||||
|
||||
153
exporter.go
153
exporter.go
@@ -8,7 +8,7 @@ package main
|
||||
//nolint:gofumpt
|
||||
import (
|
||||
// Its important that we do these first so that we can register with the Windows service control ASAP to avoid timeouts.
|
||||
"github.com/prometheus-community/windows_exporter/pkg/initiate"
|
||||
"github.com/prometheus-community/windows_exporter/internal/windowsservice"
|
||||
|
||||
"context"
|
||||
"errors"
|
||||
@@ -20,36 +20,34 @@ import (
|
||||
"os/signal"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/config"
|
||||
"github.com/prometheus-community/windows_exporter/internal/httphandler"
|
||||
"github.com/prometheus-community/windows_exporter/internal/log"
|
||||
"github.com/prometheus-community/windows_exporter/internal/log/flag"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/config"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/httphandler"
|
||||
winlog "github.com/prometheus-community/windows_exporter/pkg/log"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/log/flag"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus/common/version"
|
||||
"github.com/prometheus/exporter-toolkit/web"
|
||||
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Mapping of priority names to uin32 values required by windows.SetPriorityClass.
|
||||
var priorityStringToInt = map[string]uint32{
|
||||
"realtime": windows.REALTIME_PRIORITY_CLASS,
|
||||
"high": windows.HIGH_PRIORITY_CLASS,
|
||||
"abovenormal": windows.ABOVE_NORMAL_PRIORITY_CLASS,
|
||||
"normal": windows.NORMAL_PRIORITY_CLASS,
|
||||
"belownormal": windows.BELOW_NORMAL_PRIORITY_CLASS,
|
||||
"low": windows.IDLE_PRIORITY_CLASS,
|
||||
}
|
||||
|
||||
func main() {
|
||||
os.Exit(run())
|
||||
exitCode := run()
|
||||
|
||||
// If we are running as a service, we need to signal the service control manager that we are done.
|
||||
if !windowsservice.IsService {
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
windowsservice.ExitCodeCh <- exitCode
|
||||
|
||||
// Wait for the service control manager to signal that we are done.
|
||||
<-windowsservice.StopCh
|
||||
}
|
||||
|
||||
func run() int {
|
||||
@@ -80,11 +78,7 @@ func run() int {
|
||||
enabledCollectors = app.Flag(
|
||||
"collectors.enabled",
|
||||
"Comma-separated list of collectors to use. Use '[defaults]' as a placeholder for all the collectors enabled by default.").
|
||||
Default(types.DefaultCollectors).String()
|
||||
printCollectors = app.Flag(
|
||||
"collectors.print",
|
||||
"If true, print available collectors and exit.",
|
||||
).Bool()
|
||||
Default(collector.DefaultCollectors).String()
|
||||
timeoutMargin = app.Flag(
|
||||
"scrape.timeout-margin",
|
||||
"Seconds to subtract from the timeout allowed by the client. Tune to allow for overhead or high loads.",
|
||||
@@ -99,8 +93,8 @@ func run() int {
|
||||
).Default("normal").String()
|
||||
)
|
||||
|
||||
winlogConfig := &winlog.Config{}
|
||||
flag.AddFlags(app, winlogConfig)
|
||||
logConfig := &log.Config{}
|
||||
flag.AddFlags(app, logConfig)
|
||||
|
||||
app.Version(version.Print("windows_exporter"))
|
||||
app.HelpFlag.Short('h')
|
||||
@@ -119,7 +113,7 @@ func run() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
logger, err := winlog.New(winlogConfig)
|
||||
logger, err := log.New(logConfig)
|
||||
if err != nil {
|
||||
//nolint:sloglint // we do not have an logger yet
|
||||
slog.Error("failed to create logger",
|
||||
@@ -161,7 +155,7 @@ func run() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
logger, err = winlog.New(winlogConfig)
|
||||
logger, err = log.New(logConfig)
|
||||
if err != nil {
|
||||
//nolint:sloglint // we do not have an logger yet
|
||||
slog.Error("failed to create logger",
|
||||
@@ -174,39 +168,26 @@ func run() int {
|
||||
|
||||
logger.Debug("Logging has Started")
|
||||
|
||||
if *printCollectors {
|
||||
printCollectorsToStdout()
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Only set process priority if a non-default and valid value has been set
|
||||
if priority, ok := priorityStringToInt[*processPriority]; ok && priority != windows.NORMAL_PRIORITY_CLASS {
|
||||
logger.Debug("setting process priority to " + *processPriority)
|
||||
|
||||
if err = setPriorityWindows(os.Getpid(), priority); err != nil {
|
||||
logger.Error("failed to set process priority",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
enabledCollectorList := utils.ExpandEnabledCollectors(*enabledCollectors)
|
||||
collectors.Enable(enabledCollectorList)
|
||||
|
||||
// Initialize collectors before loading
|
||||
if err = collectors.Build(logger); err != nil {
|
||||
logger.Error("Couldn't load collectors",
|
||||
if err = setPriorityWindows(logger, os.Getpid(), *processPriority); err != nil {
|
||||
logger.Error("failed to set process priority",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if err = collectors.SetPerfCounterQuery(logger); err != nil {
|
||||
logger.Error("Couldn't set performance counter query",
|
||||
enabledCollectorList := expandEnabledCollectors(*enabledCollectors)
|
||||
if err := collectors.Enable(enabledCollectorList); err != nil {
|
||||
logger.Error("Couldn't enable collectors",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
// Initialize collectors before loading
|
||||
if err = collectors.Build(logger); err != nil {
|
||||
logger.Error("Couldn't load collectors",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
@@ -258,7 +239,7 @@ func run() int {
|
||||
errCh <- err
|
||||
}
|
||||
|
||||
errCh <- nil
|
||||
close(errCh)
|
||||
}()
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||
@@ -267,7 +248,7 @@ func run() int {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
logger.Info("Shutting down windows_exporter via kill signal")
|
||||
case <-initiate.StopCh:
|
||||
case <-windowsservice.StopCh:
|
||||
logger.Info("Shutting down windows_exporter via service control")
|
||||
case err := <-errCh:
|
||||
if err != nil {
|
||||
@@ -289,32 +270,44 @@ func run() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func printCollectorsToStdout() {
|
||||
collectorNames := collector.Available()
|
||||
sort.Strings(collectorNames)
|
||||
|
||||
fmt.Println("Available collectors:") //nolint:forbidigo
|
||||
|
||||
for _, n := range collectorNames {
|
||||
fmt.Printf(" - %s\n", n) //nolint:forbidigo
|
||||
}
|
||||
}
|
||||
|
||||
func logCurrentUser(logger *slog.Logger) {
|
||||
if u, err := user.Current(); err == nil {
|
||||
logger.Info("Running as " + u.Username)
|
||||
|
||||
if strings.Contains(u.Username, "ContainerAdministrator") || strings.Contains(u.Username, "ContainerUser") {
|
||||
logger.Warn("Running as a preconfigured Windows Container user. This may mean you do not have Windows HostProcess containers configured correctly and some functionality will not work as expected.")
|
||||
}
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
logger.Warn("Unable to determine which user is running this exporter. More info: https://github.com/golang/go/issues/37348",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
logger.Warn("Unable to determine which user is running this exporter. More info: https://github.com/golang/go/issues/37348")
|
||||
logger.Info("Running as " + u.Username)
|
||||
|
||||
if strings.Contains(u.Username, "ContainerAdministrator") || strings.Contains(u.Username, "ContainerUser") {
|
||||
logger.Warn("Running as a preconfigured Windows Container user. This may mean you do not have Windows HostProcess containers configured correctly and some functionality will not work as expected.")
|
||||
}
|
||||
}
|
||||
|
||||
func setPriorityWindows(pid int, priority uint32) error {
|
||||
// setPriorityWindows sets the priority of the current process to the specified value.
|
||||
func setPriorityWindows(logger *slog.Logger, pid int, priority string) error {
|
||||
// Mapping of priority names to uin32 values required by windows.SetPriorityClass.
|
||||
priorityStringToInt := map[string]uint32{
|
||||
"realtime": windows.REALTIME_PRIORITY_CLASS,
|
||||
"high": windows.HIGH_PRIORITY_CLASS,
|
||||
"abovenormal": windows.ABOVE_NORMAL_PRIORITY_CLASS,
|
||||
"normal": windows.NORMAL_PRIORITY_CLASS,
|
||||
"belownormal": windows.BELOW_NORMAL_PRIORITY_CLASS,
|
||||
"low": windows.IDLE_PRIORITY_CLASS,
|
||||
}
|
||||
|
||||
winPriority, ok := priorityStringToInt[priority]
|
||||
|
||||
// Only set process priority if a non-default and valid value has been set
|
||||
if !ok || winPriority != windows.NORMAL_PRIORITY_CLASS {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Debug("setting process priority to " + priority)
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
||||
handle, err := windows.OpenProcess(
|
||||
windows.STANDARD_RIGHTS_REQUIRED|windows.SYNCHRONIZE|windows.SPECIFIC_RIGHTS_ALL,
|
||||
@@ -324,7 +317,7 @@ func setPriorityWindows(pid int, priority uint32) error {
|
||||
return fmt.Errorf("failed to open own process: %w", err)
|
||||
}
|
||||
|
||||
if err = windows.SetPriorityClass(handle, priority); err != nil {
|
||||
if err = windows.SetPriorityClass(handle, winPriority); err != nil {
|
||||
return fmt.Errorf("failed to set priority class: %w", err)
|
||||
}
|
||||
|
||||
@@ -334,3 +327,9 @@ func setPriorityWindows(pid int, priority uint32) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandEnabledCollectors(enabled string) []string {
|
||||
expanded := strings.ReplaceAll(enabled, "[defaults]", collector.DefaultCollectors)
|
||||
|
||||
return slices.Compact(strings.Split(expanded, ","))
|
||||
}
|
||||
|
||||
38
go.mod
38
go.mod
@@ -3,53 +3,53 @@ module github.com/prometheus-community/windows_exporter
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.12.6
|
||||
github.com/Microsoft/hcsshim v0.12.9
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1
|
||||
github.com/dimchansky/utfbom v1.1.1
|
||||
github.com/go-ole/go-ole v1.3.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.20.3
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.59.1
|
||||
github.com/prometheus/exporter-toolkit v0.13.0
|
||||
github.com/prometheus/common v0.60.1
|
||||
github.com/prometheus/exporter-toolkit v0.13.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/yusufpapurcu/wmi v1.2.4
|
||||
golang.org/x/sys v0.25.0
|
||||
golang.org/x/sys v0.27.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.3 // indirect
|
||||
github.com/containerd/errdefs v0.1.0 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/mdlayher/socket v0.5.1 // indirect
|
||||
github.com/mdlayher/vsock v1.2.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/grpc v1.66.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/grpc v1.67.1 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
// https://github.com/prometheus/common/pull/694
|
||||
replace github.com/prometheus/common v0.59.1 => github.com/jkroepke/prometheus-common v0.0.0-20240907211841-5f9af24b97ad
|
||||
|
||||
86
go.sum
86
go.sum
@@ -2,14 +2,16 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.12.6 h1:qEnZjoHXv+4/s0LmKZWE0/AiZmMWEIkFfWBSf1a0wlU=
|
||||
github.com/Microsoft/hcsshim v0.12.6/go.mod h1:ZABCLVcvLMjIkzr9rUGcQ1QA0p0P3Ps+d3N1g2DsFfk=
|
||||
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
|
||||
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
|
||||
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg=
|
||||
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0=
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -17,8 +19,12 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
|
||||
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
|
||||
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
|
||||
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
|
||||
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
|
||||
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso=
|
||||
github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -30,10 +36,11 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
@@ -59,12 +66,12 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jkroepke/prometheus-common v0.0.0-20240907211841-5f9af24b97ad h1:sFDfDs4nDXjES8PdrFPiXeYt8dtaxn10M/Ebxe4IuiI=
|
||||
github.com/jkroepke/prometheus-common v0.0.0-20240907211841-5f9af24b97ad/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -83,13 +90,15 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
|
||||
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/exporter-toolkit v0.13.0 h1:lmA0Q+8IaXgmFRKw09RldZmZdnvu9wwcDLIXGmTPw1c=
|
||||
github.com/prometheus/exporter-toolkit v0.13.0/go.mod h1:2uop99EZl80KdXhv/MxVI2181fMcwlsumFOqBecGkG0=
|
||||
github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
|
||||
github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
|
||||
github.com/prometheus/exporter-toolkit v0.13.1 h1:Evsh0gWQo2bdOHlnz9+0Nm7/OFfIwhE2Ws4A2jIlR04=
|
||||
github.com/prometheus/exporter-toolkit v0.13.1/go.mod h1:ujdv2YIOxtdFxxqtloLpbqmxd5J0Le6IITUvIRSWjj0=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
@@ -109,67 +118,80 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
|
||||
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -179,8 +201,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:netfx="http://wixtoolset.org/schemas/v4/wxs/netfx"
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
|
||||
xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||
<Fragment>
|
||||
<DirectoryRef Id="APPLICATIONFOLDER">
|
||||
@@ -13,7 +13,7 @@
|
||||
Start="auto"
|
||||
Type="ownProcess"
|
||||
Vital="yes"
|
||||
Arguments="--log.file eventlog [ConfigFile_NonDefault][ConfigFile_Default] [CollectorsFlag] [ListenFlag] [MetricsPathFlag] [TextfileDirsFlag] [ExtraFlags]">
|
||||
Arguments="--log.file eventlog [ConfigFileFlag] [CollectorsFlag] [ListenFlag] [MetricsPathFlag] [TextfileDirsFlag] [ExtraFlags]">
|
||||
<util:ServiceConfig
|
||||
ResetPeriodInDays="1"
|
||||
FirstFailureActionType="restart"
|
||||
@@ -35,4 +35,4 @@
|
||||
<ComponentRef Id="CreateTextfileDirectory" />
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
</Wix>
|
||||
|
||||
@@ -41,9 +41,10 @@
|
||||
Value="amus" />
|
||||
<SetProperty
|
||||
Id="CreateConfigFile"
|
||||
Value=""[%ComSpec]" /c TYPE NUL >>"[APPLICATIONFOLDER]config.yaml""
|
||||
Value=""[%ComSpec]" /c TYPE NUL >>"[ConfigFile_NonDefault][ConfigFile_Default]""
|
||||
Before="CreateConfigFile"
|
||||
Sequence="execute"
|
||||
Condition="ConfigFile_NonDefault OR ConfigFile_Default"
|
||||
/>
|
||||
<CustomAction
|
||||
Id="CreateConfigFile"
|
||||
@@ -61,7 +62,7 @@
|
||||
Condition="Installed AND (NOT REMOVE) AND (NOT UPGRADINGPRODUCTCODE)"/>
|
||||
<Custom Action="set_reinstall_all_property" Before="set_reinstallmode_property" Condition="MAINTENANCE"/>
|
||||
<Custom Action="set_reinstallmode_property" Before="LaunchConditions" Condition="MAINTENANCE"/>
|
||||
<Custom Action="CreateConfigFile" Before="InstallServices" />
|
||||
<Custom Action="CreateConfigFile" Before="InstallServices" Condition="ConfigFile_NonDefault OR ConfigFile_Default" />
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<Media Id="1" Cabinet="windows_exporter.cab" EmbedCab="yes" />
|
||||
@@ -74,8 +75,9 @@
|
||||
<SetProperty Id="ExtraFlags" After="InstallFiles" Sequence="execute" Value="[EXTRA_FLAGS]" Condition="EXTRA_FLAGS" />
|
||||
|
||||
<Property Id="CONFIG_FILE" Secure="yes" Value="config.yaml" />
|
||||
<SetProperty Id="ConfigFile_NonDefault" After="InstallFiles" Sequence="execute" Value="--config.file="[CONFIG_FILE]"" Condition="CONFIG_FILE AND CONFIG_FILE<>"config.yaml"" />
|
||||
<SetProperty Id="ConfigFile_Default" After="InstallFiles" Sequence="execute" Value="--config.file="[APPLICATIONFOLDER]config.yaml"" Condition="CONFIG_FILE="config.yaml"" />
|
||||
<SetProperty Id="ConfigFile_NonDefault" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND CONFIG_FILE<>"config.yaml"" />
|
||||
<SetProperty Id="ConfigFile_Default" After="InstallFiles" Sequence="execute" Value="[APPLICATIONFOLDER]config.yaml" Condition="CONFIG_FILE="config.yaml"" />
|
||||
<SetProperty Id="ConfigFileFlag" After="InstallFiles" Sequence="execute" Value="--config.file="[ConfigFile_NonDefault][ConfigFile_Default]"" Condition="ConfigFile_NonDefault OR ConfigFile_Default" />
|
||||
|
||||
<Property Id="LISTEN_PORT" Secure="yes" Value="9182" />
|
||||
<SetProperty Id="ListenFlag" After="InstallFiles" Sequence="execute" Value="--web.listen-address [LISTEN_ADDR]:[LISTEN_PORT]" Condition="LISTEN_ADDR<>"" OR LISTEN_PORT<>9182" />
|
||||
@@ -216,4 +218,4 @@
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Package>
|
||||
</Wix>
|
||||
</Wix>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
14
internal/collector/ad/ad_test.go
Normal file
14
internal/collector/ad/ad_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package ad_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/ad"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, ad.Name, ad.NewWithFlags)
|
||||
}
|
||||
207
internal/collector/ad/const.go
Normal file
207
internal/collector/ad/const.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package ad
|
||||
|
||||
const (
|
||||
abANRPerSec = "AB ANR/sec"
|
||||
abBrowsesPerSec = "AB Browses/sec"
|
||||
abClientSessions = "AB Client Sessions"
|
||||
abMatchesPerSec = "AB Matches/sec"
|
||||
abPropertyReadsPerSec = "AB Property Reads/sec"
|
||||
abProxyLookupsPerSec = "AB Proxy Lookups/sec"
|
||||
abSearchesPerSec = "AB Searches/sec"
|
||||
approximateHighestDNT = "Approximate highest DNT"
|
||||
atqEstimatedQueueDelay = "ATQ Estimated Queue Delay"
|
||||
atqOutstandingQueuedRequests = "ATQ Outstanding Queued Requests"
|
||||
_ = "ATQ Queue Latency"
|
||||
atqRequestLatency = "ATQ Request Latency"
|
||||
atqThreadsLDAP = "ATQ Threads LDAP"
|
||||
atqThreadsOther = "ATQ Threads Other"
|
||||
atqThreadsTotal = "ATQ Threads Total"
|
||||
baseSearchesPerSec = "Base searches/sec"
|
||||
databaseAddsPerSec = "Database adds/sec"
|
||||
databaseDeletesPerSec = "Database deletes/sec"
|
||||
databaseModifiesPerSec = "Database modifys/sec"
|
||||
databaseRecyclesPerSec = "Database recycles/sec"
|
||||
digestBindsPerSec = "Digest Binds/sec"
|
||||
_ = "DirSync session throttling rate"
|
||||
_ = "DirSync sessions in progress"
|
||||
draHighestUSNCommittedHighPart = "DRA Highest USN Committed (High part)"
|
||||
draHighestUSNCommittedLowPart = "DRA Highest USN Committed (Low part)"
|
||||
draHighestUSNIssuedHighPart = "DRA Highest USN Issued (High part)"
|
||||
draHighestUSNIssuedLowPart = "DRA Highest USN Issued (Low part)"
|
||||
draInboundBytesCompressedBetweenSitesAfterCompressionSinceBoot = "DRA Inbound Bytes Compressed (Between Sites, After Compression) Since Boot"
|
||||
draInboundBytesCompressedBetweenSitesAfterCompressionPerSec = "DRA Inbound Bytes Compressed (Between Sites, After Compression)/sec"
|
||||
draInboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot = "DRA Inbound Bytes Compressed (Between Sites, Before Compression) Since Boot"
|
||||
draInboundBytesCompressedBetweenSitesBeforeCompressionPerSec = "DRA Inbound Bytes Compressed (Between Sites, Before Compression)/sec"
|
||||
draInboundBytesNotCompressedWithinSiteSinceBoot = "DRA Inbound Bytes Not Compressed (Within Site) Since Boot"
|
||||
draInboundBytesNotCompressedWithinSitePerSec = "DRA Inbound Bytes Not Compressed (Within Site)/sec"
|
||||
draInboundBytesTotalSinceBoot = "DRA Inbound Bytes Total Since Boot"
|
||||
draInboundBytesTotalPerSec = "DRA Inbound Bytes Total/sec"
|
||||
draInboundFullSyncObjectsRemaining = "DRA Inbound Full Sync Objects Remaining"
|
||||
draInboundLinkValueUpdatesRemainingInPacket = "DRA Inbound Link Value Updates Remaining in Packet"
|
||||
_ = "DRA Inbound Link Values/sec"
|
||||
draInboundObjectUpdatesRemainingInPacket = "DRA Inbound Object Updates Remaining in Packet"
|
||||
draInboundObjectsAppliedPerSec = "DRA Inbound Objects Applied/sec"
|
||||
draInboundObjectsFilteredPerSec = "DRA Inbound Objects Filtered/sec"
|
||||
draInboundObjectsPerSec = "DRA Inbound Objects/sec"
|
||||
draInboundPropertiesAppliedPerSec = "DRA Inbound Properties Applied/sec"
|
||||
draInboundPropertiesFilteredPerSec = "DRA Inbound Properties Filtered/sec"
|
||||
draInboundPropertiesTotalPerSec = "DRA Inbound Properties Total/sec"
|
||||
_ = "DRA Inbound Sync Link Deletion/sec"
|
||||
draInboundTotalUpdatesRemainingInPacket = "DRA Inbound Total Updates Remaining in Packet"
|
||||
draInboundValuesDNsOnlyPerSec = "DRA Inbound Values (DNs only)/sec"
|
||||
draInboundValuesTotalPerSec = "DRA Inbound Values Total/sec"
|
||||
_ = "DRA number of NC replication calls since boot"
|
||||
_ = "DRA number of successful NC replication calls since boot"
|
||||
draOutboundBytesCompressedBetweenSitesAfterCompressionSinceBoot = "DRA Outbound Bytes Compressed (Between Sites, After Compression) Since Boot"
|
||||
draOutboundBytesCompressedBetweenSitesAfterCompressionPerSec = "DRA Outbound Bytes Compressed (Between Sites, After Compression)/sec"
|
||||
draOutboundBytesCompressedBetweenSitesBeforeCompressionSinceBoot = "DRA Outbound Bytes Compressed (Between Sites, Before Compression) Since Boot"
|
||||
draOutboundBytesCompressedBetweenSitesBeforeCompressionPerSec = "DRA Outbound Bytes Compressed (Between Sites, Before Compression)/sec"
|
||||
draOutboundBytesNotCompressedWithinSiteSinceBoot = "DRA Outbound Bytes Not Compressed (Within Site) Since Boot"
|
||||
draOutboundBytesNotCompressedWithinSitePerSec = "DRA Outbound Bytes Not Compressed (Within Site)/sec"
|
||||
draOutboundBytesTotalSinceBoot = "DRA Outbound Bytes Total Since Boot"
|
||||
draOutboundBytesTotalPerSec = "DRA Outbound Bytes Total/sec"
|
||||
draOutboundObjectsFilteredPerSec = "DRA Outbound Objects Filtered/sec"
|
||||
draOutboundObjectsPerSec = "DRA Outbound Objects/sec"
|
||||
draOutboundPropertiesPerSec = "DRA Outbound Properties/sec"
|
||||
draOutboundValuesDNsOnlyPerSec = "DRA Outbound Values (DNs only)/sec"
|
||||
draOutboundValuesTotalPerSec = "DRA Outbound Values Total/sec"
|
||||
draPendingReplicationOperations = "DRA Pending Replication Operations"
|
||||
draPendingReplicationSynchronizations = "DRA Pending Replication Synchronizations"
|
||||
draSyncFailuresOnSchemaMismatch = "DRA Sync Failures on Schema Mismatch"
|
||||
draSyncRequestsMade = "DRA Sync Requests Made"
|
||||
draSyncRequestsSuccessful = "DRA Sync Requests Successful"
|
||||
draThreadsGettingNCChanges = "DRA Threads Getting NC Changes"
|
||||
draThreadsGettingNCChangesHoldingSemaphore = "DRA Threads Getting NC Changes Holding Semaphore"
|
||||
_ = "DRA total number of Busy failures since boot"
|
||||
_ = "DRA total number of MissingParent failures since boot"
|
||||
_ = "DRA total number of NotEnoughAttrs/MissingObject failures since boot"
|
||||
_ = "DRA total number of Preempted failures since boot"
|
||||
_ = "DRA total time of applying replication package since boot"
|
||||
_ = "DRA total time of NC replication calls since boot"
|
||||
_ = "DRA total time of successful NC replication calls since boot"
|
||||
_ = "DRA total time of successfully applying replication package since boot"
|
||||
_ = "DRA total time on waiting async replication packages since boot"
|
||||
_ = "DRA total time on waiting sync replication packages since boot"
|
||||
dsPercentReadsFromDRA = "DS % Reads from DRA"
|
||||
dsPercentReadsFromKCC = "DS % Reads from KCC"
|
||||
dsPercentReadsFromLSA = "DS % Reads from LSA"
|
||||
dsPercentReadsFromNSPI = "DS % Reads from NSPI"
|
||||
dsPercentReadsFromNTDSAPI = "DS % Reads from NTDSAPI"
|
||||
dsPercentReadsFromSAM = "DS % Reads from SAM"
|
||||
dsPercentReadsOther = "DS % Reads Other"
|
||||
dsPercentSearchesFromDRA = "DS % Searches from DRA"
|
||||
dsPercentSearchesFromKCC = "DS % Searches from KCC"
|
||||
dsPercentSearchesFromLDAP = "DS % Searches from LDAP"
|
||||
dsPercentSearchesFromLSA = "DS % Searches from LSA"
|
||||
dsPercentSearchesFromNSPI = "DS % Searches from NSPI"
|
||||
dsPercentSearchesFromNTDSAPI = "DS % Searches from NTDSAPI"
|
||||
dsPercentSearchesFromSAM = "DS % Searches from SAM"
|
||||
dsPercentSearchesOther = "DS % Searches Other"
|
||||
dsPercentWritesFromDRA = "DS % Writes from DRA"
|
||||
dsPercentWritesFromKCC = "DS % Writes from KCC"
|
||||
dsPercentWritesFromLDAP = "DS % Writes from LDAP"
|
||||
dsPercentWritesFromLSA = "DS % Writes from LSA"
|
||||
dsPercentWritesFromNSPI = "DS % Writes from NSPI"
|
||||
dsPercentWritesFromNTDSAPI = "DS % Writes from NTDSAPI"
|
||||
dsPercentWritesFromSAM = "DS % Writes from SAM"
|
||||
dsPercentWritesOther = "DS % Writes Other"
|
||||
dsClientBindsPerSec = "DS Client Binds/sec"
|
||||
dsClientNameTranslationsPerSec = "DS Client Name Translations/sec"
|
||||
dsDirectoryReadsPerSec = "DS Directory Reads/sec"
|
||||
dsDirectorySearchesPerSec = "DS Directory Searches/sec"
|
||||
dsDirectoryWritesPerSec = "DS Directory Writes/sec"
|
||||
dsMonitorListSize = "DS Monitor List Size"
|
||||
dsNameCacheHitRate = "DS Name Cache hit rate"
|
||||
dsNotifyQueueSize = "DS Notify Queue Size"
|
||||
dsSearchSubOperationsPerSec = "DS Search sub-operations/sec"
|
||||
dsSecurityDescriptorPropagationsEvents = "DS Security Descriptor Propagations Events"
|
||||
dsSecurityDescriptorPropagatorAverageExclusionTime = "DS Security Descriptor Propagator Average Exclusion Time"
|
||||
dsSecurityDescriptorPropagatorRuntimeQueue = "DS Security Descriptor Propagator Runtime Queue"
|
||||
dsSecurityDescriptorSubOperationsPerSec = "DS Security Descriptor sub-operations/sec"
|
||||
dsServerBindsPerSec = "DS Server Binds/sec"
|
||||
dsServerNameTranslationsPerSec = "DS Server Name Translations/sec"
|
||||
dsThreadsInUse = "DS Threads in Use"
|
||||
_ = "Error eventlogs since boot"
|
||||
_ = "Error events since boot"
|
||||
externalBindsPerSec = "External Binds/sec"
|
||||
fastBindsPerSec = "Fast Binds/sec"
|
||||
_ = "Fatal events since boot"
|
||||
_ = "Info eventlogs since boot"
|
||||
ldapActiveThreads = "LDAP Active Threads"
|
||||
_ = "LDAP Add Operations"
|
||||
_ = "LDAP Add Operations/sec"
|
||||
_ = "LDAP batch slots available"
|
||||
ldapBindTime = "LDAP Bind Time"
|
||||
_ = "LDAP busy retries"
|
||||
_ = "LDAP busy retries/sec"
|
||||
ldapClientSessions = "LDAP Client Sessions"
|
||||
ldapClosedConnectionsPerSec = "LDAP Closed Connections/sec"
|
||||
_ = "LDAP Delete Operations"
|
||||
_ = "LDAP Delete Operations/sec"
|
||||
_ = "LDAP Modify DN Operations"
|
||||
_ = "LDAP Modify DN Operations/sec"
|
||||
_ = "LDAP Modify Operations"
|
||||
_ = "LDAP Modify Operations/sec"
|
||||
ldapNewConnectionsPerSec = "LDAP New Connections/sec"
|
||||
ldapNewSSLConnectionsPerSec = "LDAP New SSL Connections/sec"
|
||||
_ = "LDAP Outbound Bytes"
|
||||
_ = "LDAP Outbound Bytes/sec"
|
||||
_ = "LDAP Page Search Cache entries count"
|
||||
_ = "LDAP Page Search Cache size"
|
||||
ldapSearchesPerSec = "LDAP Searches/sec"
|
||||
ldapSuccessfulBindsPerSec = "LDAP Successful Binds/sec"
|
||||
_ = "LDAP Threads Sleeping on BUSY"
|
||||
ldapUDPOperationsPerSec = "LDAP UDP operations/sec"
|
||||
ldapWritesPerSec = "LDAP Writes/sec"
|
||||
linkValuesCleanedPerSec = "Link Values Cleaned/sec"
|
||||
_ = "Links added"
|
||||
_ = "Links added/sec"
|
||||
_ = "Links visited"
|
||||
_ = "Links visited/sec"
|
||||
_ = "Logical link deletes"
|
||||
_ = "Logical link deletes/sec"
|
||||
negotiatedBindsPerSec = "Negotiated Binds/sec"
|
||||
ntlmBindsPerSec = "NTLM Binds/sec"
|
||||
_ = "Objects returned"
|
||||
_ = "Objects returned/sec"
|
||||
_ = "Objects visited"
|
||||
_ = "Objects visited/sec"
|
||||
oneLevelSearchesPerSec = "Onelevel searches/sec"
|
||||
_ = "PDC failed password update notifications"
|
||||
_ = "PDC password update notifications/sec"
|
||||
_ = "PDC successful password update notifications"
|
||||
phantomsCleanedPerSec = "Phantoms Cleaned/sec"
|
||||
phantomsVisitedPerSec = "Phantoms Visited/sec"
|
||||
_ = "Physical link deletes"
|
||||
_ = "Physical link deletes/sec"
|
||||
_ = "Replicate Single Object operations"
|
||||
_ = "Replicate Single Object operations/sec"
|
||||
_ = "RID Pool invalidations since boot"
|
||||
_ = "RID Pool request failures since boot"
|
||||
_ = "RID Pool request successes since boot"
|
||||
samAccountGroupEvaluationLatency = "SAM Account Group Evaluation Latency"
|
||||
samDisplayInformationQueriesPerSec = "SAM Display Information Queries/sec"
|
||||
samDomainLocalGroupMembershipEvaluationsPerSec = "SAM Domain Local Group Membership Evaluations/sec"
|
||||
samEnumerationsPerSec = "SAM Enumerations/sec"
|
||||
samGCEvaluationsPerSec = "SAM GC Evaluations/sec"
|
||||
samGlobalGroupMembershipEvaluationsPerSec = "SAM Global Group Membership Evaluations/sec"
|
||||
samMachineCreationAttemptsPerSec = "SAM Machine Creation Attempts/sec"
|
||||
samMembershipChangesPerSec = "SAM Membership Changes/sec"
|
||||
samNonTransitiveMembershipEvaluationsPerSec = "SAM Non-Transitive Membership Evaluations/sec"
|
||||
samPasswordChangesPerSec = "SAM Password Changes/sec"
|
||||
samResourceGroupEvaluationLatency = "SAM Resource Group Evaluation Latency"
|
||||
samSuccessfulComputerCreationsPerSecIncludesAllRequests = "SAM Successful Computer Creations/sec: Includes all requests"
|
||||
samSuccessfulUserCreationsPerSec = "SAM Successful User Creations/sec"
|
||||
samTransitiveMembershipEvaluationsPerSec = "SAM Transitive Membership Evaluations/sec"
|
||||
samUniversalGroupMembershipEvaluationsPerSec = "SAM Universal Group Membership Evaluations/sec"
|
||||
samUserCreationAttemptsPerSec = "SAM User Creation Attempts/sec"
|
||||
simpleBindsPerSec = "Simple Binds/sec"
|
||||
subtreeSearchesPerSec = "Subtree searches/sec"
|
||||
tombstonesGarbageCollectedPerSec = "Tombstones Garbage Collected/sec"
|
||||
tombstonesVisitedPerSec = "Tombstones Visited/sec"
|
||||
transitiveOperationsMillisecondsRun = "Transitive operations milliseconds run"
|
||||
transitiveOperationsPerSec = "Transitive operations/sec"
|
||||
transitiveSubOperationsPerSec = "Transitive suboperations/sec"
|
||||
_ = "Warning eventlogs since boot"
|
||||
_ = "Warning events since boot"
|
||||
)
|
||||
@@ -4,15 +4,15 @@ package adcs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "adcs"
|
||||
@@ -24,6 +24,8 @@ var ConfigDefaults = Config{}
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollector *perfdata.Collector
|
||||
|
||||
challengeResponseProcessingTime *prometheus.Desc
|
||||
challengeResponsesPerSecond *prometheus.Desc
|
||||
failedRequestsPerSecond *prometheus.Desc
|
||||
@@ -59,15 +61,34 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{"Certification Authority"}, nil
|
||||
}
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollector.Close()
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector("Certification Authority", perfdata.InstanceAll, []string{
|
||||
requestsPerSecond,
|
||||
requestProcessingTime,
|
||||
retrievalsPerSecond,
|
||||
retrievalProcessingTime,
|
||||
failedRequestsPerSecond,
|
||||
issuedRequestsPerSecond,
|
||||
pendingRequestsPerSecond,
|
||||
requestCryptographicSigningTime,
|
||||
requestPolicyModuleProcessingTime,
|
||||
challengeResponsesPerSecond,
|
||||
challengeResponseProcessingTime,
|
||||
signedCertificateTimestampListsPerSecond,
|
||||
signedCertificateTimestampListProcessingTime,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Certification Authority collector: %w", err)
|
||||
}
|
||||
|
||||
c.requestsPerSecond = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
|
||||
"Total certificate requests processed",
|
||||
@@ -150,134 +171,94 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collectADCSCounters(ctx, logger, ch); err != nil {
|
||||
logger.Error("failed collecting ADCS metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type perflibADCS struct {
|
||||
Name string
|
||||
RequestsPerSecond float64 `perflib:"Requests/sec"`
|
||||
RequestProcessingTime float64 `perflib:"Request processing time (ms)"`
|
||||
RetrievalsPerSecond float64 `perflib:"Retrievals/sec"`
|
||||
RetrievalProcessingTime float64 `perflib:"Retrieval processing time (ms)"`
|
||||
FailedRequestsPerSecond float64 `perflib:"Failed Requests/sec"`
|
||||
IssuedRequestsPerSecond float64 `perflib:"Issued Requests/sec"`
|
||||
PendingRequestsPerSecond float64 `perflib:"Pending Requests/sec"`
|
||||
RequestCryptographicSigningTime float64 `perflib:"Request cryptographic signing time (ms)"`
|
||||
RequestPolicyModuleProcessingTime float64 `perflib:"Request policy module processing time (ms)"`
|
||||
ChallengeResponsesPerSecond float64 `perflib:"Challenge Responses/sec"`
|
||||
ChallengeResponseProcessingTime float64 `perflib:"Challenge Response processing time (ms)"`
|
||||
SignedCertificateTimestampListsPerSecond float64 `perflib:"Signed Certificate Timestamp Lists/sec"`
|
||||
SignedCertificateTimestampListProcessingTime float64 `perflib:"Signed Certificate Timestamp List processing time (ms)"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectADCSCounters(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
dst := make([]perflibADCS, 0)
|
||||
|
||||
if _, ok := ctx.PerfObjects["Certification Authority"]; !ok {
|
||||
return errors.New("perflib did not contain an entry for Certification Authority")
|
||||
}
|
||||
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Certification Authority"], &dst, logger)
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to collect Certification Authority (ADCS) metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(dst) == 0 {
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for Certification Authority (ADCS) returned empty result set")
|
||||
}
|
||||
|
||||
for _, d := range dst {
|
||||
n := strings.ToLower(d.Name)
|
||||
if n == "" {
|
||||
continue
|
||||
}
|
||||
for name, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
d.RequestsPerSecond,
|
||||
d.Name,
|
||||
data[requestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(d.RequestProcessingTime),
|
||||
d.Name,
|
||||
utils.MilliSecToSec(data[requestProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retrievalsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
d.RetrievalsPerSecond,
|
||||
d.Name,
|
||||
data[retrievalsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retrievalProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(d.RetrievalProcessingTime),
|
||||
d.Name,
|
||||
utils.MilliSecToSec(data[retrievalProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failedRequestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
d.FailedRequestsPerSecond,
|
||||
d.Name,
|
||||
data[failedRequestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.issuedRequestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
d.IssuedRequestsPerSecond,
|
||||
d.Name,
|
||||
data[issuedRequestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pendingRequestsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
d.PendingRequestsPerSecond,
|
||||
d.Name,
|
||||
data[pendingRequestsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestCryptographicSigningTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(d.RequestCryptographicSigningTime),
|
||||
d.Name,
|
||||
utils.MilliSecToSec(data[requestCryptographicSigningTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestPolicyModuleProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(d.RequestPolicyModuleProcessingTime),
|
||||
d.Name,
|
||||
utils.MilliSecToSec(data[requestPolicyModuleProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.challengeResponsesPerSecond,
|
||||
prometheus.CounterValue,
|
||||
d.ChallengeResponsesPerSecond,
|
||||
d.Name,
|
||||
data[challengeResponsesPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.challengeResponseProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(d.ChallengeResponseProcessingTime),
|
||||
d.Name,
|
||||
utils.MilliSecToSec(data[challengeResponseProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.signedCertificateTimestampListsPerSecond,
|
||||
prometheus.CounterValue,
|
||||
d.SignedCertificateTimestampListsPerSecond,
|
||||
d.Name,
|
||||
data[signedCertificateTimestampListsPerSecond].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.signedCertificateTimestampListProcessingTime,
|
||||
prometheus.GaugeValue,
|
||||
utils.MilliSecToSec(d.SignedCertificateTimestampListProcessingTime),
|
||||
d.Name,
|
||||
utils.MilliSecToSec(data[signedCertificateTimestampListProcessingTime].FirstValue),
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
14
internal/collector/adcs/adcs_test.go
Normal file
14
internal/collector/adcs/adcs_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package adcs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/adcs"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, adcs.Name, adcs.NewWithFlags)
|
||||
}
|
||||
19
internal/collector/adcs/const.go
Normal file
19
internal/collector/adcs/const.go
Normal file
@@ -0,0 +1,19 @@
|
||||
//go:build windows
|
||||
|
||||
package adcs
|
||||
|
||||
const (
|
||||
challengeResponseProcessingTime = "Challenge Response processing time (ms)"
|
||||
challengeResponsesPerSecond = "Challenge Responses/sec"
|
||||
failedRequestsPerSecond = "Failed Requests/sec"
|
||||
issuedRequestsPerSecond = "Issued Requests/sec"
|
||||
pendingRequestsPerSecond = "Pending Requests/sec"
|
||||
requestCryptographicSigningTime = "Request cryptographic signing time (ms)"
|
||||
requestPolicyModuleProcessingTime = "Request policy module processing time (ms)"
|
||||
requestProcessingTime = "Request processing time (ms)"
|
||||
requestsPerSecond = "Requests/sec"
|
||||
retrievalProcessingTime = "Retrieval processing time (ms)"
|
||||
retrievalsPerSecond = "Retrievals/sec"
|
||||
signedCertificateTimestampListProcessingTime = "Signed Certificate Timestamp List processing time (ms)"
|
||||
signedCertificateTimestampListsPerSecond = "Signed Certificate Timestamp Lists/sec"
|
||||
)
|
||||
@@ -3,14 +3,18 @@
|
||||
package adfs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"math"
|
||||
"slices"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "adfs"
|
||||
@@ -22,6 +26,8 @@ var ConfigDefaults = Config{}
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollector *perfdata.Collector
|
||||
|
||||
adLoginConnectionFailures *prometheus.Desc
|
||||
artifactDBFailures *prometheus.Desc
|
||||
avgArtifactDBQueryTime *prometheus.Desc
|
||||
@@ -63,8 +69,8 @@ type Collector struct {
|
||||
upAuthenticationFailures *prometheus.Desc
|
||||
upAuthentications *prometheus.Desc
|
||||
windowsIntegratedAuthentications *prometheus.Desc
|
||||
wsfedTokenRequests *prometheus.Desc
|
||||
wstrustTokenRequests *prometheus.Desc
|
||||
wsFedTokenRequests *prometheus.Desc
|
||||
wsTrustTokenRequests *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
@@ -87,15 +93,64 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{"AD FS"}, nil
|
||||
}
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollector.Close()
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector("AD FS", perfdata.InstanceAll, []string{
|
||||
adLoginConnectionFailures,
|
||||
certificateAuthentications,
|
||||
deviceAuthentications,
|
||||
extranetAccountLockouts,
|
||||
federatedAuthentications,
|
||||
passportAuthentications,
|
||||
passiveRequests,
|
||||
passwordChangeFailed,
|
||||
passwordChangeSucceeded,
|
||||
tokenRequests,
|
||||
windowsIntegratedAuthentications,
|
||||
oAuthAuthZRequests,
|
||||
oAuthClientAuthentications,
|
||||
oAuthClientAuthenticationFailures,
|
||||
oAuthClientCredentialRequestFailures,
|
||||
oAuthClientCredentialRequests,
|
||||
oAuthClientPrivateKeyJWTAuthenticationFailures,
|
||||
oAuthClientPrivateKeyJWTAuthentications,
|
||||
oAuthClientBasicAuthenticationFailures,
|
||||
oAuthClientBasicAuthentications,
|
||||
oAuthClientSecretPostAuthenticationFailures,
|
||||
oAuthClientSecretPostAuthentications,
|
||||
oAuthClientWindowsAuthenticationFailures,
|
||||
oAuthClientWindowsAuthentications,
|
||||
oAuthLogonCertRequestFailures,
|
||||
oAuthLogonCertTokenRequests,
|
||||
oAuthPasswordGrantRequestFailures,
|
||||
oAuthPasswordGrantRequests,
|
||||
oAuthTokenRequests,
|
||||
samlPTokenRequests,
|
||||
ssoAuthenticationFailures,
|
||||
ssoAuthentications,
|
||||
wsFedTokenRequests,
|
||||
wsTrustTokenRequests,
|
||||
usernamePasswordAuthenticationFailures,
|
||||
usernamePasswordAuthentications,
|
||||
externalAuthentications,
|
||||
externalAuthNFailures,
|
||||
artifactDBFailures,
|
||||
avgArtifactDBQueryTime,
|
||||
configDBFailures,
|
||||
avgConfigDBQueryTime,
|
||||
federationMetadataRequests,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create AD FS collector: %w", err)
|
||||
}
|
||||
|
||||
c.adLoginConnectionFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ad_login_connection_failures_total"),
|
||||
"Total number of connection failures to an Active Directory domain controller",
|
||||
@@ -288,13 +343,13 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.wsfedTokenRequests = prometheus.NewDesc(
|
||||
c.wsFedTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wsfed_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Fed protocol",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.wstrustTokenRequests = prometheus.NewDesc(
|
||||
c.wsTrustTokenRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "wstrust_token_requests_success_total"),
|
||||
"Total number of successful RP tokens issued over WS-Trust protocol",
|
||||
nil,
|
||||
@@ -358,318 +413,280 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type perflibADFS struct {
|
||||
AdLoginConnectionFailures float64 `perflib:"AD Login Connection Failures"`
|
||||
CertificateAuthentications float64 `perflib:"Certificate Authentications"`
|
||||
DeviceAuthentications float64 `perflib:"Device Authentications"`
|
||||
ExtranetAccountLockouts float64 `perflib:"Extranet Account Lockouts"`
|
||||
FederatedAuthentications float64 `perflib:"Federated Authentications"`
|
||||
PassportAuthentications float64 `perflib:"Microsoft Passport Authentications"`
|
||||
PassiveRequests float64 `perflib:"Passive Requests"`
|
||||
PasswordChangeFailed float64 `perflib:"Password Change Failed Requests"`
|
||||
PasswordChangeSucceeded float64 `perflib:"Password Change Successful Requests"`
|
||||
TokenRequests float64 `perflib:"Token Requests"`
|
||||
WindowsIntegratedAuthentications float64 `perflib:"Windows Integrated Authentications"`
|
||||
OAuthAuthZRequests float64 `perflib:"OAuth AuthZ Requests"`
|
||||
OAuthClientAuthentications float64 `perflib:"OAuth Client Authentications"`
|
||||
OAuthClientAuthenticationFailures float64 `perflib:"OAuth Client Authentications Failures"`
|
||||
OAuthClientCredentialRequestFailures float64 `perflib:"OAuth Client Credentials Request Failures"`
|
||||
OAuthClientCredentialRequests float64 `perflib:"OAuth Client Credentials Requests"`
|
||||
OAuthClientPrivKeyJWTAuthnFailures float64 `perflib:"OAuth Client Private Key Jwt Authentication Failures"`
|
||||
OAuthClientPrivKeyJWTAuthentications float64 `perflib:"OAuth Client Private Key Jwt Authentications"`
|
||||
OAuthClientBasicAuthnFailures float64 `perflib:"OAuth Client Secret Basic Authentication Failures"`
|
||||
OAuthClientBasicAuthentications float64 `perflib:"OAuth Client Secret Basic Authentication Requests"`
|
||||
OAuthClientSecretPostAuthnFailures float64 `perflib:"OAuth Client Secret Post Authentication Failures"`
|
||||
OAuthClientSecretPostAuthentications float64 `perflib:"OAuth Client Secret Post Authentications"`
|
||||
OAuthClientWindowsAuthnFailures float64 `perflib:"OAuth Client Windows Integrated Authentication Failures"`
|
||||
OAuthClientWindowsAuthentications float64 `perflib:"OAuth Client Windows Integrated Authentications"`
|
||||
OAuthLogonCertRequestFailures float64 `perflib:"OAuth Logon Certificate Request Failures"`
|
||||
OAuthLogonCertTokenRequests float64 `perflib:"OAuth Logon Certificate Token Requests"`
|
||||
OAuthPasswordGrantRequestFailures float64 `perflib:"OAuth Password Grant Request Failures"`
|
||||
OAuthPasswordGrantRequests float64 `perflib:"OAuth Password Grant Requests"`
|
||||
OAuthTokenRequests float64 `perflib:"OAuth Token Requests"`
|
||||
SAMLPTokenRequests float64 `perflib:"SAML-P Token Requests"`
|
||||
SSOAuthenticationFailures float64 `perflib:"SSO Authentication Failures"`
|
||||
SSOAuthentications float64 `perflib:"SSO Authentications"`
|
||||
WSFedTokenRequests float64 `perflib:"WS-Fed Token Requests"`
|
||||
WSTrustTokenRequests float64 `perflib:"WS-Trust Token Requests"`
|
||||
UsernamePasswordAuthnFailures float64 `perflib:"U/P Authentication Failures"`
|
||||
UsernamePasswordAuthentications float64 `perflib:"U/P Authentications"`
|
||||
ExternalAuthentications float64 `perflib:"External Authentications"`
|
||||
ExternalAuthNFailures float64 `perflib:"External Authentication Failures"`
|
||||
ArtifactDBFailures float64 `perflib:"Artifact Database Connection Failures"`
|
||||
AvgArtifactDBQueryTime float64 `perflib:"Average Artifact Database Query Time"`
|
||||
ConfigDBFailures float64 `perflib:"Configuration Database Connection Failures"`
|
||||
AvgConfigDBQueryTime float64 `perflib:"Average Config Database Query Time"`
|
||||
FederationMetadataRequests float64 `perflib:"Federation Metadata Requests"`
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
var adfsData []perflibADFS
|
||||
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["AD FS"], &adfsData, logger)
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
data, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to collect ADFS metrics: %w", err)
|
||||
}
|
||||
|
||||
instanceKey := slices.Collect(maps.Keys(data))
|
||||
|
||||
if len(instanceKey) == 0 {
|
||||
return errors.New("perflib query for ADFS returned empty result set")
|
||||
}
|
||||
|
||||
adfsData, ok := data[instanceKey[0]]
|
||||
|
||||
if !ok {
|
||||
return errors.New("perflib query for ADFS returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.adLoginConnectionFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].AdLoginConnectionFailures,
|
||||
adfsData[adLoginConnectionFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.certificateAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].CertificateAuthentications,
|
||||
adfsData[certificateAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.deviceAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].DeviceAuthentications,
|
||||
adfsData[deviceAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.extranetAccountLockouts,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].ExtranetAccountLockouts,
|
||||
adfsData[extranetAccountLockouts].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.federatedAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].FederatedAuthentications,
|
||||
adfsData[federatedAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passportAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].PassportAuthentications,
|
||||
adfsData[passportAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passiveRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].PassiveRequests,
|
||||
adfsData[passiveRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passwordChangeFailed,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].PasswordChangeFailed,
|
||||
adfsData[passwordChangeFailed].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.passwordChangeSucceeded,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].PasswordChangeSucceeded,
|
||||
adfsData[passwordChangeSucceeded].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.tokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].TokenRequests,
|
||||
adfsData[tokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.windowsIntegratedAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].WindowsIntegratedAuthentications,
|
||||
adfsData[windowsIntegratedAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthAuthZRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthAuthZRequests,
|
||||
adfsData[oAuthAuthZRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientAuthentications,
|
||||
adfsData[oAuthClientAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientAuthenticationsFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientAuthenticationFailures,
|
||||
adfsData[oAuthClientAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientCredentialsRequestFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientCredentialRequestFailures,
|
||||
adfsData[oAuthClientCredentialRequestFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientCredentialsRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientCredentialRequests,
|
||||
adfsData[oAuthClientCredentialRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientPrivateKeyJwtAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientPrivKeyJWTAuthnFailures,
|
||||
adfsData[oAuthClientPrivateKeyJWTAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientPrivateKeyJwtAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientPrivKeyJWTAuthentications,
|
||||
adfsData[oAuthClientPrivateKeyJWTAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretBasicAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientBasicAuthnFailures,
|
||||
adfsData[oAuthClientBasicAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretBasicAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientBasicAuthentications,
|
||||
adfsData[oAuthClientBasicAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretPostAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientSecretPostAuthnFailures,
|
||||
adfsData[oAuthClientSecretPostAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientSecretPostAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientSecretPostAuthentications,
|
||||
adfsData[oAuthClientSecretPostAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientWindowsIntegratedAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientWindowsAuthnFailures,
|
||||
adfsData[oAuthClientWindowsAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthClientWindowsIntegratedAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthClientWindowsAuthentications,
|
||||
adfsData[oAuthClientWindowsAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthLogonCertificateRequestFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthLogonCertRequestFailures,
|
||||
adfsData[oAuthLogonCertRequestFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthLogonCertificateTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthLogonCertTokenRequests,
|
||||
adfsData[oAuthLogonCertTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthPasswordGrantRequestFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthPasswordGrantRequestFailures,
|
||||
adfsData[oAuthPasswordGrantRequestFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthPasswordGrantRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthPasswordGrantRequests,
|
||||
adfsData[oAuthPasswordGrantRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.oAuthTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].OAuthTokenRequests,
|
||||
adfsData[oAuthTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.samlPTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].SAMLPTokenRequests,
|
||||
adfsData[samlPTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ssoAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].SSOAuthenticationFailures,
|
||||
adfsData[ssoAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ssoAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].SSOAuthentications,
|
||||
adfsData[ssoAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.wsfedTokenRequests,
|
||||
c.wsFedTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].WSFedTokenRequests,
|
||||
adfsData[wsFedTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.wstrustTokenRequests,
|
||||
c.wsTrustTokenRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].WSTrustTokenRequests,
|
||||
adfsData[wsTrustTokenRequests].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.upAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].UsernamePasswordAuthnFailures,
|
||||
adfsData[usernamePasswordAuthenticationFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.upAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].UsernamePasswordAuthentications,
|
||||
adfsData[usernamePasswordAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalAuthenticationFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].ExternalAuthNFailures,
|
||||
adfsData[externalAuthNFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalAuthentications,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].ExternalAuthentications,
|
||||
adfsData[externalAuthentications].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.artifactDBFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].ArtifactDBFailures,
|
||||
adfsData[artifactDBFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.avgArtifactDBQueryTime,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].AvgArtifactDBQueryTime*math.Pow(10, -8),
|
||||
adfsData[avgArtifactDBQueryTime].FirstValue*math.Pow(10, -8),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.configDBFailures,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].ConfigDBFailures,
|
||||
adfsData[configDBFailures].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.avgConfigDBQueryTime,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].AvgConfigDBQueryTime*math.Pow(10, -8),
|
||||
adfsData[avgConfigDBQueryTime].FirstValue*math.Pow(10, -8),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.federationMetadataRequests,
|
||||
prometheus.CounterValue,
|
||||
adfsData[0].FederationMetadataRequests,
|
||||
adfsData[federationMetadataRequests].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
14
internal/collector/adfs/adfs_test.go
Normal file
14
internal/collector/adfs/adfs_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package adfs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/adfs"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, adfs.Name, adfs.NewWithFlags)
|
||||
}
|
||||
49
internal/collector/adfs/const.go
Normal file
49
internal/collector/adfs/const.go
Normal file
@@ -0,0 +1,49 @@
|
||||
//go:build windows
|
||||
|
||||
package adfs
|
||||
|
||||
const (
|
||||
adLoginConnectionFailures = "AD Login Connection Failures"
|
||||
artifactDBFailures = "Artifact Database Connection Failures"
|
||||
avgArtifactDBQueryTime = "Average Artifact Database Query Time"
|
||||
avgConfigDBQueryTime = "Average Config Database Query Time"
|
||||
certificateAuthentications = "Certificate Authentications"
|
||||
configDBFailures = "Configuration Database Connection Failures"
|
||||
deviceAuthentications = "Device Authentications"
|
||||
externalAuthentications = "External Authentications"
|
||||
externalAuthNFailures = "External Authentication Failures"
|
||||
extranetAccountLockouts = "Extranet Account Lockouts"
|
||||
federatedAuthentications = "Federated Authentications"
|
||||
federationMetadataRequests = "Federation Metadata Requests"
|
||||
oAuthAuthZRequests = "OAuth AuthZ Requests"
|
||||
oAuthClientAuthenticationFailures = "OAuth Client Authentications Failures"
|
||||
oAuthClientAuthentications = "OAuth Client Authentications"
|
||||
oAuthClientBasicAuthenticationFailures = "OAuth Client Secret Basic Authentication Failures"
|
||||
oAuthClientBasicAuthentications = "OAuth Client Secret Basic Authentication Requests"
|
||||
oAuthClientCredentialRequestFailures = "OAuth Client Credentials Request Failures"
|
||||
oAuthClientCredentialRequests = "OAuth Client Credentials Requests"
|
||||
oAuthClientPrivateKeyJWTAuthenticationFailures = "OAuth Client Private Key Jwt Authentication Failures"
|
||||
oAuthClientPrivateKeyJWTAuthentications = "OAuth Client Private Key Jwt Authentications"
|
||||
oAuthClientSecretPostAuthenticationFailures = "OAuth Client Secret Post Authentication Failures"
|
||||
oAuthClientSecretPostAuthentications = "OAuth Client Secret Post Authentications"
|
||||
oAuthClientWindowsAuthenticationFailures = "OAuth Client Windows Integrated Authentication Failures"
|
||||
oAuthClientWindowsAuthentications = "OAuth Client Windows Integrated Authentications"
|
||||
oAuthLogonCertRequestFailures = "OAuth Logon Certificate Request Failures"
|
||||
oAuthLogonCertTokenRequests = "OAuth Logon Certificate Token Requests"
|
||||
oAuthPasswordGrantRequestFailures = "OAuth Password Grant Request Failures"
|
||||
oAuthPasswordGrantRequests = "OAuth Password Grant Requests"
|
||||
oAuthTokenRequests = "OAuth Token Requests"
|
||||
passiveRequests = "Passive Requests"
|
||||
passportAuthentications = "Microsoft Passport Authentications"
|
||||
passwordChangeFailed = "Password Change Failed Requests"
|
||||
passwordChangeSucceeded = "Password Change Successful Requests"
|
||||
samlPTokenRequests = "SAML-P Token Requests"
|
||||
ssoAuthenticationFailures = "SSO Authentication Failures"
|
||||
ssoAuthentications = "SSO Authentications"
|
||||
tokenRequests = "Token Requests"
|
||||
usernamePasswordAuthenticationFailures = "U/P Authentication Failures"
|
||||
usernamePasswordAuthentications = "U/P Authentications"
|
||||
windowsIntegratedAuthentications = "Windows Integrated Authentications"
|
||||
wsFedTokenRequests = "WS-Fed Token Requests"
|
||||
wsTrustTokenRequests = "WS-Trust Token Requests"
|
||||
)
|
||||
@@ -3,14 +3,15 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "cache"
|
||||
@@ -23,6 +24,8 @@ var ConfigDefaults = Config{}
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollector *perfdata.Collector
|
||||
|
||||
asyncCopyReadsTotal *prometheus.Desc
|
||||
asyncDataMapsTotal *prometheus.Desc
|
||||
asyncFastReadsTotal *prometheus.Desc
|
||||
@@ -74,15 +77,50 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{"Cache"}, nil
|
||||
}
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollector.Close()
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector("Cache", perfdata.InstanceAll, []string{
|
||||
asyncCopyReadsTotal,
|
||||
asyncDataMapsTotal,
|
||||
asyncFastReadsTotal,
|
||||
asyncMDLReadsTotal,
|
||||
asyncPinReadsTotal,
|
||||
copyReadHitsTotal,
|
||||
copyReadsTotal,
|
||||
dataFlushesTotal,
|
||||
dataFlushPagesTotal,
|
||||
dataMapHitsPercent,
|
||||
dataMapPinsTotal,
|
||||
dataMapsTotal,
|
||||
dirtyPages,
|
||||
dirtyPageThreshold,
|
||||
fastReadNotPossiblesTotal,
|
||||
fastReadResourceMissesTotal,
|
||||
fastReadsTotal,
|
||||
lazyWriteFlushesTotal,
|
||||
lazyWritePagesTotal,
|
||||
mdlReadHitsTotal,
|
||||
mdlReadsTotal,
|
||||
pinReadHitsTotal,
|
||||
pinReadsTotal,
|
||||
readAheadsTotal,
|
||||
syncCopyReadsTotal,
|
||||
syncDataMapsTotal,
|
||||
syncFastReadsTotal,
|
||||
syncMDLReadsTotal,
|
||||
syncPinReadsTotal,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Cache collector: %w", err)
|
||||
}
|
||||
|
||||
c.asyncCopyReadsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "async_copy_reads_total"),
|
||||
"(AsyncCopyReadsTotal)",
|
||||
@@ -262,238 +300,190 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
}
|
||||
|
||||
// Collect implements the Collector interface.
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ctx, logger, ch); err != nil {
|
||||
logger.Error("failed collecting cache metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
data, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect Cache metrics: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
cacheData, ok := data[perfdata.EmptyInstance]
|
||||
|
||||
// Perflib "Cache":
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85)
|
||||
type perflibCache struct {
|
||||
AsyncCopyReadsTotal float64 `perflib:"Async Copy Reads/sec"`
|
||||
AsyncDataMapsTotal float64 `perflib:"Async Data Maps/sec"`
|
||||
AsyncFastReadsTotal float64 `perflib:"Async Fast Reads/sec"`
|
||||
AsyncMDLReadsTotal float64 `perflib:"Async MDL Reads/sec"`
|
||||
AsyncPinReadsTotal float64 `perflib:"Async Pin Reads/sec"`
|
||||
CopyReadHitsTotal float64 `perflib:"Copy Read Hits %"`
|
||||
CopyReadsTotal float64 `perflib:"Copy Reads/sec"`
|
||||
DataFlushesTotal float64 `perflib:"Data Flushes/sec"`
|
||||
DataFlushPagesTotal float64 `perflib:"Data Flush Pages/sec"`
|
||||
DataMapHitsPercent float64 `perflib:"Data Map Hits %"`
|
||||
DataMapPinsTotal float64 `perflib:"Data Map Pins/sec"`
|
||||
DataMapsTotal float64 `perflib:"Data Maps/sec"`
|
||||
DirtyPages float64 `perflib:"Dirty Pages"`
|
||||
DirtyPageThreshold float64 `perflib:"Dirty Page Threshold"`
|
||||
FastReadNotPossiblesTotal float64 `perflib:"Fast Read Not Possibles/sec"`
|
||||
FastReadResourceMissesTotal float64 `perflib:"Fast Read Resource Misses/sec"`
|
||||
FastReadsTotal float64 `perflib:"Fast Reads/sec"`
|
||||
LazyWriteFlushesTotal float64 `perflib:"Lazy Write Flushes/sec"`
|
||||
LazyWritePagesTotal float64 `perflib:"Lazy Write Pages/sec"`
|
||||
MDLReadHitsTotal float64 `perflib:"MDL Read Hits %"`
|
||||
MDLReadsTotal float64 `perflib:"MDL Reads/sec"`
|
||||
PinReadHitsTotal float64 `perflib:"Pin Read Hits %"`
|
||||
PinReadsTotal float64 `perflib:"Pin Reads/sec"`
|
||||
ReadAheadsTotal float64 `perflib:"Read Aheads/sec"`
|
||||
SyncCopyReadsTotal float64 `perflib:"Sync Copy Reads/sec"`
|
||||
SyncDataMapsTotal float64 `perflib:"Sync Data Maps/sec"`
|
||||
SyncFastReadsTotal float64 `perflib:"Sync Fast Reads/sec"`
|
||||
SyncMDLReadsTotal float64 `perflib:"Sync MDL Reads/sec"`
|
||||
SyncPinReadsTotal float64 `perflib:"Sync Pin Reads/sec"`
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
var dst []perflibCache // Single-instance class, array is required but will have single entry.
|
||||
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["Cache"], &dst, logger); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(dst) != 1 {
|
||||
return errors.New("expected single instance of Cache")
|
||||
if !ok {
|
||||
return errors.New("perflib query for Cache returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncCopyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncCopyReadsTotal,
|
||||
cacheData[asyncCopyReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncDataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncDataMapsTotal,
|
||||
cacheData[asyncDataMapsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncFastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncFastReadsTotal,
|
||||
cacheData[asyncFastReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncMDLReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncMDLReadsTotal,
|
||||
cacheData[asyncMDLReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.asyncPinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].AsyncPinReadsTotal,
|
||||
cacheData[asyncPinReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.copyReadHitsTotal,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].CopyReadHitsTotal,
|
||||
cacheData[copyReadHitsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.copyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].CopyReadsTotal,
|
||||
cacheData[copyReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataFlushesTotal,
|
||||
cacheData[dataFlushesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataFlushPagesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataFlushPagesTotal,
|
||||
cacheData[dataFlushPagesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapHitsPercent,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DataMapHitsPercent,
|
||||
cacheData[dataMapHitsPercent].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapPinsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataMapPinsTotal,
|
||||
cacheData[dataMapPinsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].DataMapsTotal,
|
||||
cacheData[dataMapsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPages,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DirtyPages,
|
||||
cacheData[dirtyPages].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dirtyPageThreshold,
|
||||
prometheus.GaugeValue,
|
||||
dst[0].DirtyPageThreshold,
|
||||
cacheData[dirtyPageThreshold].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadNotPossiblesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadNotPossiblesTotal,
|
||||
cacheData[fastReadNotPossiblesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadResourceMissesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadResourceMissesTotal,
|
||||
cacheData[fastReadResourceMissesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].FastReadsTotal,
|
||||
cacheData[fastReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWriteFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].LazyWriteFlushesTotal,
|
||||
cacheData[lazyWriteFlushesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.lazyWritePagesTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].LazyWritePagesTotal,
|
||||
cacheData[lazyWritePagesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].MDLReadHitsTotal,
|
||||
cacheData[mdlReadHitsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mdlReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].MDLReadsTotal,
|
||||
cacheData[mdlReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PinReadHitsTotal,
|
||||
cacheData[pinReadHitsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].PinReadsTotal,
|
||||
cacheData[pinReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.readAheadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].ReadAheadsTotal,
|
||||
cacheData[readAheadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncCopyReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncCopyReadsTotal,
|
||||
cacheData[syncCopyReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncDataMapsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncDataMapsTotal,
|
||||
cacheData[syncDataMapsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncFastReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncFastReadsTotal,
|
||||
cacheData[syncFastReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncMDLReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncMDLReadsTotal,
|
||||
cacheData[syncMDLReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncPinReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
dst[0].SyncPinReadsTotal,
|
||||
cacheData[syncPinReadsTotal].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
14
internal/collector/cache/cache_test.go
vendored
Normal file
14
internal/collector/cache/cache_test.go
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package cache_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cache"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cache.Name, cache.NewWithFlags)
|
||||
}
|
||||
37
internal/collector/cache/const.go
vendored
Normal file
37
internal/collector/cache/const.go
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
//go:build windows
|
||||
|
||||
package cache
|
||||
|
||||
// Perflib "Cache":
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/aa394267(v=vs.85)
|
||||
const (
|
||||
asyncCopyReadsTotal = "Async Copy Reads/sec"
|
||||
asyncDataMapsTotal = "Async Data Maps/sec"
|
||||
asyncFastReadsTotal = "Async Fast Reads/sec"
|
||||
asyncMDLReadsTotal = "Async MDL Reads/sec"
|
||||
asyncPinReadsTotal = "Async Pin Reads/sec"
|
||||
copyReadHitsTotal = "Copy Read Hits %"
|
||||
copyReadsTotal = "Copy Reads/sec"
|
||||
dataFlushesTotal = "Data Flushes/sec"
|
||||
dataFlushPagesTotal = "Data Flush Pages/sec"
|
||||
dataMapHitsPercent = "Data Map Hits %"
|
||||
dataMapPinsTotal = "Data Map Pins/sec"
|
||||
dataMapsTotal = "Data Maps/sec"
|
||||
dirtyPages = "Dirty Pages"
|
||||
dirtyPageThreshold = "Dirty Page Threshold"
|
||||
fastReadNotPossiblesTotal = "Fast Read Not Possibles/sec"
|
||||
fastReadResourceMissesTotal = "Fast Read Resource Misses/sec"
|
||||
fastReadsTotal = "Fast Reads/sec"
|
||||
lazyWriteFlushesTotal = "Lazy Write Flushes/sec"
|
||||
lazyWritePagesTotal = "Lazy Write Pages/sec"
|
||||
mdlReadHitsTotal = "MDL Read Hits %"
|
||||
mdlReadsTotal = "MDL Reads/sec"
|
||||
pinReadHitsTotal = "Pin Read Hits %"
|
||||
pinReadsTotal = "Pin Reads/sec"
|
||||
readAheadsTotal = "Read Aheads/sec"
|
||||
syncCopyReadsTotal = "Sync Copy Reads/sec"
|
||||
syncDataMapsTotal = "Sync Data Maps/sec"
|
||||
syncFastReadsTotal = "Sync Fast Reads/sec"
|
||||
syncMDLReadsTotal = "Sync MDL Reads/sec"
|
||||
syncPinReadsTotal = "Sync Pin Reads/sec"
|
||||
)
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "container"
|
||||
@@ -26,6 +26,8 @@ var ConfigDefaults = Config{}
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
logger *slog.Logger
|
||||
|
||||
// Presence
|
||||
containerAvailable *prometheus.Desc
|
||||
|
||||
@@ -78,15 +80,13 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
c.logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
c.containerAvailable = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "available"),
|
||||
"Available",
|
||||
@@ -201,28 +201,11 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(logger, ch); err != nil {
|
||||
logger.Error("failed collecting collector metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
// Types Container is passed to get the containers compute systems only
|
||||
containers, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{Types: []string{"Container"}})
|
||||
if err != nil {
|
||||
logger.Error("Err in Getting containers",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
return fmt.Errorf("error in fetching containers: %w", err)
|
||||
}
|
||||
|
||||
count := len(containers)
|
||||
@@ -243,14 +226,14 @@ func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) er
|
||||
for _, containerDetails := range containers {
|
||||
containerIdWithPrefix := getContainerIdWithPrefix(containerDetails)
|
||||
|
||||
if err = c.collectContainer(logger, ch, containerDetails, containerIdWithPrefix); err != nil {
|
||||
if err = c.collectContainer(ch, containerDetails, containerIdWithPrefix); err != nil {
|
||||
if hcsshim.IsNotExist(err) {
|
||||
logger.Debug("err in fetching container statistics",
|
||||
c.logger.Debug("err in fetching container statistics",
|
||||
slog.String("container_id", containerDetails.ID),
|
||||
slog.Any("err", err),
|
||||
)
|
||||
} else {
|
||||
logger.Error("err in fetching container statistics",
|
||||
c.logger.Error("err in fetching container statistics",
|
||||
slog.String("container_id", containerDetails.ID),
|
||||
slog.Any("err", err),
|
||||
)
|
||||
@@ -264,7 +247,7 @@ func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) er
|
||||
containerPrefixes[containerDetails.ID] = containerIdWithPrefix
|
||||
}
|
||||
|
||||
if err = c.collectNetworkMetrics(logger, ch, containerPrefixes); err != nil {
|
||||
if err = c.collectNetworkMetrics(ch, containerPrefixes); err != nil {
|
||||
return fmt.Errorf("error in fetching container network statistics: %w", err)
|
||||
}
|
||||
|
||||
@@ -275,7 +258,7 @@ func (c *Collector) collect(logger *slog.Logger, ch chan<- prometheus.Metric) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.Metric, containerDetails hcsshim.ContainerProperties, containerIdWithPrefix string) error {
|
||||
func (c *Collector) collectContainer(ch chan<- prometheus.Metric, containerDetails hcsshim.ContainerProperties, containerIdWithPrefix string) error {
|
||||
container, err := hcsshim.OpenContainer(containerDetails.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in opening container: %w", err)
|
||||
@@ -287,7 +270,7 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M
|
||||
}
|
||||
|
||||
if err := container.Close(); err != nil {
|
||||
logger.Error("error in closing container",
|
||||
c.logger.Error("error in closing container",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
}
|
||||
@@ -325,19 +308,19 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeTotal,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Processor.TotalRuntime100ns)*perflib.TicksToSecondScaleFactor,
|
||||
float64(containerStats.Processor.TotalRuntime100ns)*perfdata.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeUser,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Processor.RuntimeUser100ns)*perflib.TicksToSecondScaleFactor,
|
||||
float64(containerStats.Processor.RuntimeUser100ns)*perfdata.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.runtimeKernel,
|
||||
prometheus.CounterValue,
|
||||
float64(containerStats.Processor.RuntimeKernel100ns)*perflib.TicksToSecondScaleFactor,
|
||||
float64(containerStats.Processor.RuntimeKernel100ns)*perfdata.TicksToSecondScaleFactor,
|
||||
containerIdWithPrefix,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
@@ -372,24 +355,20 @@ func (c *Collector) collectContainer(logger *slog.Logger, ch chan<- prometheus.M
|
||||
// With HNSv2, the network stats must be collected from hcsshim.HNSListEndpointRequest.
|
||||
// Network statistics from the container.Statistics() are providing data only, if HNSv1 is used.
|
||||
// Ref: https://github.com/prometheus-community/windows_exporter/pull/1218
|
||||
func (c *Collector) collectNetworkMetrics(logger *slog.Logger, ch chan<- prometheus.Metric, containerPrefixes map[string]string) error {
|
||||
func (c *Collector) collectNetworkMetrics(ch chan<- prometheus.Metric, containerPrefixes map[string]string) error {
|
||||
hnsEndpoints, err := hcsshim.HNSListEndpointRequest()
|
||||
if err != nil {
|
||||
logger.Warn("Failed to collect network stats for containers")
|
||||
|
||||
return err
|
||||
return fmt.Errorf("error in fetching HNS endpoints: %w", err)
|
||||
}
|
||||
|
||||
if len(hnsEndpoints) == 0 {
|
||||
logger.Info("No network stats for containers to collect")
|
||||
|
||||
return nil
|
||||
return errors.New("no network stats for containers to collect")
|
||||
}
|
||||
|
||||
for _, endpoint := range hnsEndpoints {
|
||||
endpointStats, err := hcsshim.GetHNSEndpointStats(endpoint.Id)
|
||||
if err != nil {
|
||||
logger.Warn("Failed to collect network stats for interface "+endpoint.Id,
|
||||
c.logger.Warn("Failed to collect network stats for interface "+endpoint.Id,
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
@@ -400,7 +379,7 @@ func (c *Collector) collectNetworkMetrics(logger *slog.Logger, ch chan<- prometh
|
||||
containerIdWithPrefix, ok := containerPrefixes[containerId]
|
||||
|
||||
if !ok {
|
||||
logger.Debug("Failed to collect network stats for container " + containerId)
|
||||
c.logger.Debug("Failed to collect network stats for container " + containerId)
|
||||
|
||||
continue
|
||||
}
|
||||
14
internal/collector/container/container_test.go
Normal file
14
internal/collector/container/container_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package container_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/container"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, container.Name, container.NewWithFlags)
|
||||
}
|
||||
30
internal/collector/cpu/const.go
Normal file
30
internal/collector/cpu/const.go
Normal file
@@ -0,0 +1,30 @@
|
||||
//go:build windows
|
||||
|
||||
package cpu
|
||||
|
||||
// Processor performance counters.
|
||||
const (
|
||||
c1TimeSeconds = "% C1 Time"
|
||||
c2TimeSeconds = "% C2 Time"
|
||||
c3TimeSeconds = "% C3 Time"
|
||||
c1TransitionsTotal = "C1 Transitions/sec"
|
||||
c2TransitionsTotal = "C2 Transitions/sec"
|
||||
c3TransitionsTotal = "C3 Transitions/sec"
|
||||
clockInterruptsTotal = "Clock Interrupts/sec"
|
||||
dpcQueuedPerSecond = "DPCs Queued/sec"
|
||||
dpcTimeSeconds = "% DPC Time"
|
||||
idleBreakEventsTotal = "Idle Break Events/sec"
|
||||
idleTimeSeconds = "% Idle Time"
|
||||
interruptsTotal = "Interrupts/sec"
|
||||
interruptTimeSeconds = "% Interrupt Time"
|
||||
parkingStatus = "Parking Status"
|
||||
performanceLimitPercent = "% Performance Limit"
|
||||
priorityTimeSeconds = "% Priority Time"
|
||||
privilegedTimeSeconds = "% Privileged Time"
|
||||
privilegedUtilitySeconds = "% Privileged Utility"
|
||||
processorFrequencyMHz = "Processor Frequency"
|
||||
processorPerformance = "% Processor Performance"
|
||||
processorTimeSeconds = "% Processor Time"
|
||||
processorUtilityRate = "% Processor Utility"
|
||||
userTimeSeconds = "% User Time"
|
||||
)
|
||||
@@ -3,14 +3,16 @@
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "cpu"
|
||||
@@ -22,6 +24,13 @@ var ConfigDefaults = Config{}
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollector *perfdata.Collector
|
||||
|
||||
mu sync.Mutex
|
||||
|
||||
processorRTCValues map[string]utils.Counter
|
||||
processorMPerfValues map[string]utils.Counter
|
||||
|
||||
logicalProcessors *prometheus.Desc
|
||||
cStateSecondsTotal *prometheus.Desc
|
||||
timeTotal *prometheus.Desc
|
||||
@@ -58,15 +67,46 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{"Processor Information"}, nil
|
||||
}
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollector.Close()
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
var err error
|
||||
|
||||
c.mu = sync.Mutex{}
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector("Processor Information", perfdata.InstanceAll, []string{
|
||||
c1TimeSeconds,
|
||||
c2TimeSeconds,
|
||||
c3TimeSeconds,
|
||||
c1TransitionsTotal,
|
||||
c2TransitionsTotal,
|
||||
c3TransitionsTotal,
|
||||
clockInterruptsTotal,
|
||||
dpcQueuedPerSecond,
|
||||
dpcTimeSeconds,
|
||||
idleBreakEventsTotal,
|
||||
idleTimeSeconds,
|
||||
interruptsTotal,
|
||||
interruptTimeSeconds,
|
||||
parkingStatus,
|
||||
performanceLimitPercent,
|
||||
priorityTimeSeconds,
|
||||
privilegedTimeSeconds,
|
||||
privilegedUtilitySeconds,
|
||||
processorFrequencyMHz,
|
||||
processorPerformance,
|
||||
processorTimeSeconds,
|
||||
processorUtilityRate,
|
||||
userTimeSeconds,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Processor Information collector: %w", err)
|
||||
}
|
||||
|
||||
c.logicalProcessors = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "logical_processor"),
|
||||
"Total number of logical processors",
|
||||
@@ -98,7 +138,6 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
[]string{"core"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.cStateSecondsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cstate_seconds_total"),
|
||||
"Time spent in low-power idle state",
|
||||
@@ -178,180 +217,164 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.processorRTCValues = map[string]utils.Counter{}
|
||||
c.processorMPerfValues = map[string]utils.Counter{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
c.mu.Lock() // Lock is needed to prevent concurrent map access to c.processorRTCValues
|
||||
defer c.mu.Unlock()
|
||||
|
||||
return c.CollectFull(ctx, logger, ch)
|
||||
}
|
||||
|
||||
type perflibProcessorInformation struct {
|
||||
Name string
|
||||
C1TimeSeconds float64 `perflib:"% C1 Time"`
|
||||
C2TimeSeconds float64 `perflib:"% C2 Time"`
|
||||
C3TimeSeconds float64 `perflib:"% C3 Time"`
|
||||
C1TransitionsTotal float64 `perflib:"C1 Transitions/sec"`
|
||||
C2TransitionsTotal float64 `perflib:"C2 Transitions/sec"`
|
||||
C3TransitionsTotal float64 `perflib:"C3 Transitions/sec"`
|
||||
ClockInterruptsTotal float64 `perflib:"Clock Interrupts/sec"`
|
||||
DPCsQueuedTotal float64 `perflib:"DPCs Queued/sec"`
|
||||
DPCTimeSeconds float64 `perflib:"% DPC Time"`
|
||||
IdleBreakEventsTotal float64 `perflib:"Idle Break Events/sec"`
|
||||
IdleTimeSeconds float64 `perflib:"% Idle Time"`
|
||||
InterruptsTotal float64 `perflib:"Interrupts/sec"`
|
||||
InterruptTimeSeconds float64 `perflib:"% Interrupt Time"`
|
||||
ParkingStatus float64 `perflib:"Parking Status"`
|
||||
PerformanceLimitPercent float64 `perflib:"% Performance Limit"`
|
||||
PriorityTimeSeconds float64 `perflib:"% Priority Time"`
|
||||
PrivilegedTimeSeconds float64 `perflib:"% Privileged Time"`
|
||||
PrivilegedUtilitySeconds float64 `perflib:"% Privileged Utility"`
|
||||
ProcessorFrequencyMHz float64 `perflib:"Processor Frequency"`
|
||||
ProcessorPerformance float64 `perflib:"% Processor Performance"`
|
||||
ProcessorMPerf float64 `perflib:"% Processor Performance,secondvalue"`
|
||||
ProcessorTimeSeconds float64 `perflib:"% Processor Time"`
|
||||
ProcessorUtilityRate float64 `perflib:"% Processor Utility"`
|
||||
ProcessorRTC float64 `perflib:"% Processor Utility,secondvalue"`
|
||||
UserTimeSeconds float64 `perflib:"% User Time"`
|
||||
}
|
||||
|
||||
func (c *Collector) CollectFull(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
data := make([]perflibProcessorInformation, 0)
|
||||
|
||||
err := perflib.UnmarshalObject(ctx.PerfObjects["Processor Information"], &data, logger)
|
||||
data, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to collect Processor Information metrics: %w", err)
|
||||
}
|
||||
|
||||
var coreCount float64
|
||||
|
||||
for _, cpu := range data {
|
||||
if strings.Contains(strings.ToLower(cpu.Name), "_total") {
|
||||
continue
|
||||
for core, coreData := range data {
|
||||
coreCount++
|
||||
|
||||
var (
|
||||
counterProcessorRTCValues utils.Counter
|
||||
counterProcessorMPerfValues utils.Counter
|
||||
ok bool
|
||||
)
|
||||
|
||||
if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
|
||||
counterProcessorRTCValues.AddValue(uint32(coreData[processorUtilityRate].SecondValue))
|
||||
} else {
|
||||
counterProcessorRTCValues = utils.NewCounter(uint32(coreData[privilegedUtilitySeconds].SecondValue))
|
||||
}
|
||||
|
||||
core := cpu.Name
|
||||
c.processorRTCValues[core] = counterProcessorRTCValues
|
||||
|
||||
coreCount++
|
||||
if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
|
||||
counterProcessorMPerfValues.AddValue(uint32(coreData[processorPerformance].SecondValue))
|
||||
} else {
|
||||
counterProcessorMPerfValues = utils.NewCounter(uint32(coreData[processorPerformance].SecondValue))
|
||||
}
|
||||
|
||||
c.processorMPerfValues[core] = counterProcessorMPerfValues
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.C1TimeSeconds,
|
||||
coreData[c1TimeSeconds].FirstValue,
|
||||
core, "c1",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.C2TimeSeconds,
|
||||
coreData[c2TimeSeconds].FirstValue,
|
||||
core, "c2",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.cStateSecondsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.C3TimeSeconds,
|
||||
coreData[c3TimeSeconds].FirstValue,
|
||||
core, "c3",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.IdleTimeSeconds,
|
||||
coreData[idleTimeSeconds].FirstValue,
|
||||
core, "idle",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.InterruptTimeSeconds,
|
||||
coreData[interruptTimeSeconds].FirstValue,
|
||||
core, "interrupt",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.DPCTimeSeconds,
|
||||
coreData[dpcTimeSeconds].FirstValue,
|
||||
core, "dpc",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.PrivilegedTimeSeconds,
|
||||
coreData[privilegedTimeSeconds].FirstValue,
|
||||
core, "privileged",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.UserTimeSeconds,
|
||||
coreData[userTimeSeconds].FirstValue,
|
||||
core, "user",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.interruptsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.InterruptsTotal,
|
||||
coreData[interruptsTotal].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dpcsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.DPCsQueuedTotal,
|
||||
coreData[dpcQueuedPerSecond].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clockInterruptsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.ClockInterruptsTotal,
|
||||
coreData[clockInterruptsTotal].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.idleBreakEventsTotal,
|
||||
prometheus.CounterValue,
|
||||
cpu.IdleBreakEventsTotal,
|
||||
coreData[idleBreakEventsTotal].FirstValue,
|
||||
core,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.parkingStatus,
|
||||
prometheus.GaugeValue,
|
||||
cpu.ParkingStatus,
|
||||
coreData[parkingStatus].FirstValue,
|
||||
core,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorFrequencyMHz,
|
||||
prometheus.GaugeValue,
|
||||
cpu.ProcessorFrequencyMHz,
|
||||
coreData[processorFrequencyMHz].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorPerformance,
|
||||
prometheus.CounterValue,
|
||||
cpu.ProcessorPerformance,
|
||||
coreData[processorPerformance].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorMPerf,
|
||||
prometheus.CounterValue,
|
||||
cpu.ProcessorMPerf,
|
||||
counterProcessorMPerfValues.Value(),
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorRTC,
|
||||
prometheus.CounterValue,
|
||||
cpu.ProcessorRTC,
|
||||
counterProcessorRTCValues.Value(),
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorUtility,
|
||||
prometheus.CounterValue,
|
||||
cpu.ProcessorUtilityRate,
|
||||
coreData[processorUtilityRate].FirstValue,
|
||||
core,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.processorPrivilegedUtility,
|
||||
prometheus.CounterValue,
|
||||
cpu.PrivilegedUtilitySeconds,
|
||||
coreData[privilegedUtilitySeconds].FirstValue,
|
||||
core,
|
||||
)
|
||||
}
|
||||
18
internal/collector/cpu/cpu_test.go
Normal file
18
internal/collector/cpu/cpu_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
//go:build windows
|
||||
|
||||
package cpu_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cpu"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cpu.Name, cpu.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
testutils.TestCollector(t, cpu.New, nil)
|
||||
}
|
||||
@@ -4,19 +4,18 @@ package cpu_info
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const (
|
||||
Name = "cpu_info"
|
||||
)
|
||||
const Name = "cpu_info"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
@@ -24,9 +23,9 @@ var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_Processor.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
wmiClient *wmi.Client
|
||||
config Config
|
||||
miSession *mi.Session
|
||||
miQuery mi.Query
|
||||
|
||||
cpuInfo *prometheus.Desc
|
||||
cpuCoreCount *prometheus.Desc
|
||||
@@ -57,20 +56,23 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
|
||||
return errors.New("wmiClient or SWbemServicesClient is nil")
|
||||
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
|
||||
if miSession == nil {
|
||||
return errors.New("miSession is nil")
|
||||
}
|
||||
|
||||
c.wmiClient = wmiClient
|
||||
miQuery, err := mi.NewQuery("SELECT Architecture, DeviceId, Description, Family, L2CacheSize, L3CacheSize, Name, ThreadCount, NumberOfCores, NumberOfEnabledCore, NumberOfLogicalProcessors FROM Win32_Processor")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
c.miQuery = miQuery
|
||||
c.miSession = miSession
|
||||
|
||||
c.cpuInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, "", Name),
|
||||
"Labelled CPU information as provided by Win32_Processor",
|
||||
@@ -135,46 +137,28 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type win32Processor struct {
|
||||
Architecture uint32
|
||||
DeviceID string
|
||||
Description string
|
||||
Family uint16
|
||||
L2CacheSize uint32
|
||||
L3CacheSize uint32
|
||||
Name string
|
||||
ThreadCount uint32
|
||||
NumberOfCores uint32
|
||||
NumberOfEnabledCore uint32
|
||||
NumberOfLogicalProcessors uint32
|
||||
type miProcessor struct {
|
||||
Architecture uint32 `mi:"Architecture"`
|
||||
DeviceID string `mi:"DeviceID"`
|
||||
Description string `mi:"Description"`
|
||||
Family uint16 `mi:"Family"`
|
||||
L2CacheSize uint32 `mi:"L2CacheSize"`
|
||||
L3CacheSize uint32 `mi:"L3CacheSize"`
|
||||
Name string `mi:"Name"`
|
||||
ThreadCount uint32 `mi:"ThreadCount"`
|
||||
NumberOfCores uint32 `mi:"NumberOfCores"`
|
||||
NumberOfEnabledCore uint32 `mi:"NumberOfEnabledCore"`
|
||||
NumberOfLogicalProcessors uint32 `mi:"NumberOfLogicalProcessors"`
|
||||
|
||||
Total int
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
logger.Error("failed collecting cpu_info metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []win32Processor
|
||||
// We use a static query here because the provided methods in wmi.go all issue a SELECT *;
|
||||
// This results in the time-consuming LoadPercentage field being read which seems to measure each CPU
|
||||
// serially over a 1 second interval, so the scrape time is at least 1s * num_sockets
|
||||
if err := c.wmiClient.Query("SELECT Architecture, DeviceId, Description, Family, L2CacheSize, L3CacheSize, Name, ThreadCount, NumberOfCores, NumberOfEnabledCore, NumberOfLogicalProcessors FROM Win32_Processor", &dst); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(dst) == 0 {
|
||||
return errors.New("WMI query returned empty result set")
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []miProcessor
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
// Some CPUs end up exposing trailing spaces for certain strings, so clean them up
|
||||
18
internal/collector/cpu_info/cpu_info_test.go
Normal file
18
internal/collector/cpu_info/cpu_info_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
//go:build windows
|
||||
|
||||
package cpu_info_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cpu_info"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cpu_info.Name, cpu_info.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
testutils.TestCollector(t, cpu_info.New, nil)
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/headers/sysinfoapi"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/headers/sysinfoapi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "cs"
|
||||
@@ -53,15 +53,11 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
logger.Warn("The cs collector is deprecated and will be removed in a future release. " +
|
||||
"Logical processors has been moved to cpu_info collector. " +
|
||||
"Physical memory has been moved to memory collector. " +
|
||||
@@ -95,20 +91,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
logger.Error("failed collecting cs metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
// Get systeminfo for number of processors
|
||||
systemInfo := sysinfoapi.GetSystemInfo()
|
||||
|
||||
14
internal/collector/cs/cs_test.go
Normal file
14
internal/collector/cs/cs_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package cs_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/cs"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, cs.Name, cs.NewWithFlags)
|
||||
}
|
||||
44
internal/collector/dfsr/const.go
Normal file
44
internal/collector/dfsr/const.go
Normal file
@@ -0,0 +1,44 @@
|
||||
//go:build windows
|
||||
|
||||
package dfsr
|
||||
|
||||
const (
|
||||
// Connection Perflib: "DFS Replication Service Connections".
|
||||
bytesReceivedTotal = "Total Bytes Received"
|
||||
|
||||
// Folder Perflib: "DFS Replicated Folder".
|
||||
bandwidthSavingsUsingDFSReplicationTotal = "Bandwidth Savings Using DFS Replication"
|
||||
compressedSizeOfFilesReceivedTotal = "Compressed Size of Files Received"
|
||||
conflictBytesCleanedUpTotal = "Conflict Bytes Cleaned Up"
|
||||
conflictBytesGeneratedTotal = "Conflict Bytes Generated"
|
||||
conflictFilesCleanedUpTotal = "Conflict Files Cleaned Up"
|
||||
conflictFilesGeneratedTotal = "Conflict Files Generated"
|
||||
conflictFolderCleanupsCompletedTotal = "Conflict folder Cleanups Completed"
|
||||
conflictSpaceInUse = "Conflict Space In Use"
|
||||
deletedSpaceInUse = "Deleted Space In Use"
|
||||
deletedBytesCleanedUpTotal = "Deleted Bytes Cleaned Up"
|
||||
deletedBytesGeneratedTotal = "Deleted Bytes Generated"
|
||||
deletedFilesCleanedUpTotal = "Deleted Files Cleaned Up"
|
||||
deletedFilesGeneratedTotal = "Deleted Files Generated"
|
||||
fileInstallsRetriedTotal = "File Installs Retried"
|
||||
fileInstallsSucceededTotal = "File Installs Succeeded"
|
||||
filesReceivedTotal = "Total Files Received"
|
||||
rdcBytesReceivedTotal = "RDC Bytes Received"
|
||||
rdcCompressedSizeOfFilesReceivedTotal = "RDC Compressed Size of Files Received"
|
||||
rdcNumberOfFilesReceivedTotal = "RDC Number of Files Received"
|
||||
rdcSizeOfFilesReceivedTotal = "RDC Size of Files Received"
|
||||
sizeOfFilesReceivedTotal = "Size of Files Received"
|
||||
stagingSpaceInUse = "Staging Space In Use"
|
||||
stagingBytesCleanedUpTotal = "Staging Bytes Cleaned Up"
|
||||
stagingBytesGeneratedTotal = "Staging Bytes Generated"
|
||||
stagingFilesCleanedUpTotal = "Staging Files Cleaned Up"
|
||||
stagingFilesGeneratedTotal = "Staging Files Generated"
|
||||
updatesDroppedTotal = "Updates Dropped"
|
||||
|
||||
// Volume Perflib: "DFS Replication Service Volumes".
|
||||
databaseCommitsTotal = "Database Commits"
|
||||
databaseLookupsTotal = "Database Lookups"
|
||||
usnJournalRecordsReadTotal = "USN Journal Records Read"
|
||||
usnJournalRecordsAcceptedTotal = "USN Journal Records Accepted"
|
||||
usnJournalUnreadPercentage = "USN Journal Records Unread Percentage"
|
||||
)
|
||||
@@ -3,15 +3,17 @@
|
||||
package dfsr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "dfsr"
|
||||
@@ -28,6 +30,10 @@ var ConfigDefaults = Config{
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollectorConnection *perfdata.Collector
|
||||
perfDataCollectorFolder *perfdata.Collector
|
||||
perfDataCollectorVolume *perfdata.Collector
|
||||
|
||||
// connection source
|
||||
connectionBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
|
||||
connectionBytesReceivedTotal *prometheus.Desc
|
||||
@@ -36,17 +42,17 @@ type Collector struct {
|
||||
connectionRDCBytesReceivedTotal *prometheus.Desc
|
||||
connectionRDCCompressedSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
connectionRDCSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
connectionRDCNumberofFilesReceivedTotal *prometheus.Desc
|
||||
connectionRDCNumberOfFilesReceivedTotal *prometheus.Desc
|
||||
connectionSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
|
||||
// folder source
|
||||
folderBandwidthSavingsUsingDFSReplicationTotal *prometheus.Desc
|
||||
folderCompressedSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderConflictBytesCleanedupTotal *prometheus.Desc
|
||||
folderConflictBytesCleanedUpTotal *prometheus.Desc
|
||||
folderConflictBytesGeneratedTotal *prometheus.Desc
|
||||
folderConflictFilesCleanedUpTotal *prometheus.Desc
|
||||
folderConflictFilesGeneratedTotal *prometheus.Desc
|
||||
folderConflictfolderCleanupsCompletedTotal *prometheus.Desc
|
||||
folderConflictFolderCleanupsCompletedTotal *prometheus.Desc
|
||||
folderConflictSpaceInUse *prometheus.Desc
|
||||
folderDeletedSpaceInUse *prometheus.Desc
|
||||
folderDeletedBytesCleanedUpTotal *prometheus.Desc
|
||||
@@ -58,7 +64,7 @@ type Collector struct {
|
||||
folderFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCBytesReceivedTotal *prometheus.Desc
|
||||
folderRDCCompressedSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCNumberofFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCNumberOfFilesReceivedTotal *prometheus.Desc
|
||||
folderRDCSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderSizeOfFilesReceivedTotal *prometheus.Desc
|
||||
folderStagingSpaceInUse *prometheus.Desc
|
||||
@@ -74,29 +80,6 @@ type Collector struct {
|
||||
volumeUSNJournalUnreadPercentage *prometheus.Desc
|
||||
volumeUSNJournalRecordsAcceptedTotal *prometheus.Desc
|
||||
volumeUSNJournalRecordsReadTotal *prometheus.Desc
|
||||
|
||||
// Map of child Collector functions used during collection
|
||||
dfsrChildCollectors []dfsrCollectorFunc
|
||||
}
|
||||
|
||||
type dfsrCollectorFunc func(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error
|
||||
|
||||
// Map Perflib sources to DFSR Collector names
|
||||
// e.g, volume -> DFS Replication Service Volumes.
|
||||
func dfsrGetPerfObjectName(collector string) string {
|
||||
prefix := "DFS "
|
||||
suffix := ""
|
||||
|
||||
switch collector {
|
||||
case "connection":
|
||||
suffix = "Replication Connections"
|
||||
case "folder":
|
||||
suffix = "Replicated Folders"
|
||||
case "volume":
|
||||
suffix = "Replication Service Volumes"
|
||||
}
|
||||
|
||||
return prefix + suffix
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
@@ -119,10 +102,11 @@ func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
c.config.CollectorsEnabled = make([]string, 0)
|
||||
|
||||
var collectorsEnabled string
|
||||
|
||||
app.Flag("collectors.dfsr.sources-enabled", "Comma-separated list of DFSR Perflib sources to use.").
|
||||
app.Flag("collector.dfsr.sources-enabled", "Comma-separated list of DFSR Perflib sources to use.").
|
||||
Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
@@ -138,27 +122,93 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||
expandedChildCollectors := slices.Compact(c.config.CollectorsEnabled)
|
||||
perflibDependencies := make([]string, 0, len(expandedChildCollectors))
|
||||
|
||||
for _, source := range expandedChildCollectors {
|
||||
perflibDependencies = append(perflibDependencies, dfsrGetPerfObjectName(source))
|
||||
func (c *Collector) Close() error {
|
||||
if slices.Contains(c.config.CollectorsEnabled, "connection") {
|
||||
c.perfDataCollectorConnection.Close()
|
||||
}
|
||||
|
||||
return perflibDependencies, nil
|
||||
}
|
||||
if slices.Contains(c.config.CollectorsEnabled, "folder") {
|
||||
c.perfDataCollectorFolder.Close()
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "volume") {
|
||||
c.perfDataCollectorVolume.Close()
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
logger.Info("dfsr collector is in an experimental state! Metrics for this collector have not been tested.")
|
||||
|
||||
var err error
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "connection") {
|
||||
c.perfDataCollectorConnection, err = perfdata.NewCollector("DFS Replication Connections", perfdata.InstanceAll, []string{
|
||||
bandwidthSavingsUsingDFSReplicationTotal,
|
||||
bytesReceivedTotal,
|
||||
compressedSizeOfFilesReceivedTotal,
|
||||
filesReceivedTotal,
|
||||
rdcBytesReceivedTotal,
|
||||
rdcCompressedSizeOfFilesReceivedTotal,
|
||||
rdcNumberOfFilesReceivedTotal,
|
||||
rdcSizeOfFilesReceivedTotal,
|
||||
sizeOfFilesReceivedTotal,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DFS Replication Connections collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "folder") {
|
||||
c.perfDataCollectorFolder, err = perfdata.NewCollector("DFS Replicated Folders", perfdata.InstanceAll, []string{
|
||||
bandwidthSavingsUsingDFSReplicationTotal,
|
||||
compressedSizeOfFilesReceivedTotal,
|
||||
conflictBytesCleanedUpTotal,
|
||||
conflictBytesGeneratedTotal,
|
||||
conflictFilesCleanedUpTotal,
|
||||
conflictFilesGeneratedTotal,
|
||||
conflictFolderCleanupsCompletedTotal,
|
||||
conflictSpaceInUse,
|
||||
deletedSpaceInUse,
|
||||
deletedBytesCleanedUpTotal,
|
||||
deletedBytesGeneratedTotal,
|
||||
deletedFilesCleanedUpTotal,
|
||||
deletedFilesGeneratedTotal,
|
||||
fileInstallsRetriedTotal,
|
||||
fileInstallsSucceededTotal,
|
||||
filesReceivedTotal,
|
||||
rdcBytesReceivedTotal,
|
||||
rdcCompressedSizeOfFilesReceivedTotal,
|
||||
rdcNumberOfFilesReceivedTotal,
|
||||
rdcSizeOfFilesReceivedTotal,
|
||||
sizeOfFilesReceivedTotal,
|
||||
stagingSpaceInUse,
|
||||
stagingBytesCleanedUpTotal,
|
||||
stagingBytesGeneratedTotal,
|
||||
stagingFilesCleanedUpTotal,
|
||||
stagingFilesGeneratedTotal,
|
||||
updatesDroppedTotal,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DFS Replicated Folders collector: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "volume") {
|
||||
c.perfDataCollectorVolume, err = perfdata.NewCollector("DFS Replication Service Volumes", perfdata.InstanceAll, []string{
|
||||
databaseCommitsTotal,
|
||||
databaseLookupsTotal,
|
||||
usnJournalRecordsReadTotal,
|
||||
usnJournalRecordsAcceptedTotal,
|
||||
usnJournalUnreadPercentage,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DFS Replication Service Volumes collector: %w", err)
|
||||
}
|
||||
}
|
||||
// connection
|
||||
c.connectionBandwidthSavingsUsingDFSReplicationTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_bandwidth_savings_using_dfs_replication_bytes_total"),
|
||||
@@ -202,7 +252,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.connectionRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
|
||||
c.connectionRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_received_files_total"),
|
||||
"Total number of files received using remote differential compression",
|
||||
[]string{"name"},
|
||||
@@ -238,7 +288,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.folderConflictBytesCleanedupTotal = prometheus.NewDesc(
|
||||
c.folderConflictBytesCleanedUpTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_cleaned_up_bytes_total"),
|
||||
"Total size of conflict loser files and folders deleted from the Conflict and Deleted folder, in bytes",
|
||||
[]string{"name"},
|
||||
@@ -266,7 +316,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.folderConflictfolderCleanupsCompletedTotal = prometheus.NewDesc(
|
||||
c.folderConflictFolderCleanupsCompletedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_folder_cleanups_total"),
|
||||
"Number of deletions of conflict loser files and folders in the Conflict and Deleted",
|
||||
[]string{"name"},
|
||||
@@ -350,7 +400,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.folderRDCNumberofFilesReceivedTotal = prometheus.NewDesc(
|
||||
c.folderRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_received_files_total"),
|
||||
"Total number of files received with Remote Differential Compression",
|
||||
[]string{"name"},
|
||||
@@ -449,428 +499,355 @@ func (c *Collector) Build(logger *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
// Perflib sources are dynamic, depending on the enabled child collectors
|
||||
expandedChildCollectors := slices.Compact(c.config.CollectorsEnabled)
|
||||
c.dfsrChildCollectors = c.getDFSRChildCollectors(expandedChildCollectors)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Maps enabled child collectors names to their relevant collection function,
|
||||
// for use in Collector.Collect().
|
||||
func (c *Collector) getDFSRChildCollectors(enabledCollectors []string) []dfsrCollectorFunc {
|
||||
var dfsrCollectors []dfsrCollectorFunc
|
||||
|
||||
for _, collector := range enabledCollectors {
|
||||
switch collector {
|
||||
case "connection":
|
||||
dfsrCollectors = append(dfsrCollectors, c.collectConnection)
|
||||
case "folder":
|
||||
dfsrCollectors = append(dfsrCollectors, c.collectFolder)
|
||||
case "volume":
|
||||
dfsrCollectors = append(dfsrCollectors, c.collectVolume)
|
||||
}
|
||||
}
|
||||
|
||||
return dfsrCollectors
|
||||
}
|
||||
|
||||
// Collect implements the Collector interface.
|
||||
// Sends metric values for each metric to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
for _, fn := range c.dfsrChildCollectors {
|
||||
err := fn(ctx, logger, ch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
errs := make([]error, 0, 3)
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, "connection") {
|
||||
errs = append(errs, c.collectPDHConnection(ch))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PerflibDFSRConnection Perflib: "DFS Replication Service Connections".
|
||||
type PerflibDFSRConnection struct {
|
||||
Name string
|
||||
|
||||
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
|
||||
BytesReceivedTotal float64 `perflib:"Total Bytes Received"`
|
||||
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
|
||||
FilesReceivedTotal float64 `perflib:"Total Files Received"`
|
||||
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
|
||||
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
|
||||
RDCNumberofFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
|
||||
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
|
||||
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectConnection(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
var dst []PerflibDFSRConnection
|
||||
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Connections"], &dst, logger); err != nil {
|
||||
return err
|
||||
if slices.Contains(c.config.CollectorsEnabled, "folder") {
|
||||
errs = append(errs, c.collectPDHFolder(ch))
|
||||
}
|
||||
|
||||
for _, connection := range dst {
|
||||
if slices.Contains(c.config.CollectorsEnabled, "volume") {
|
||||
errs = append(errs, c.collectPDHVolume(ch))
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (c *Collector) collectPDHConnection(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorConnection.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DFS Replication Connections metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for DFS Replication Connections returned empty result set")
|
||||
}
|
||||
|
||||
for name, connection := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionBandwidthSavingsUsingDFSReplicationTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.BandwidthSavingsUsingDFSReplicationTotal,
|
||||
connection.Name,
|
||||
connection[bandwidthSavingsUsingDFSReplicationTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionBytesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.BytesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[bytesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.CompressedSizeOfFilesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[compressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.FilesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[filesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCBytesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.RDCBytesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[rdcBytesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.RDCCompressedSizeOfFilesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[rdcCompressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.RDCSizeOfFilesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[rdcSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionRDCNumberofFilesReceivedTotal,
|
||||
c.connectionRDCNumberOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.RDCNumberofFilesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[rdcNumberOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
connection.SizeOfFilesReceivedTotal,
|
||||
connection.Name,
|
||||
connection[sizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// perflibDFSRFolder Perflib: "DFS Replicated Folder".
|
||||
type perflibDFSRFolder struct {
|
||||
Name string
|
||||
|
||||
BandwidthSavingsUsingDFSReplicationTotal float64 `perflib:"Bandwidth Savings Using DFS Replication"`
|
||||
CompressedSizeOfFilesReceivedTotal float64 `perflib:"Compressed Size of Files Received"`
|
||||
ConflictBytesCleanedupTotal float64 `perflib:"Conflict Bytes Cleaned Up"`
|
||||
ConflictBytesGeneratedTotal float64 `perflib:"Conflict Bytes Generated"`
|
||||
ConflictFilesCleanedUpTotal float64 `perflib:"Conflict Files Cleaned Up"`
|
||||
ConflictFilesGeneratedTotal float64 `perflib:"Conflict Files Generated"`
|
||||
ConflictFolderCleanupsCompletedTotal float64 `perflib:"Conflict folder Cleanups Completed"`
|
||||
ConflictSpaceInUse float64 `perflib:"Conflict Space In Use"`
|
||||
DeletedSpaceInUse float64 `perflib:"Deleted Space In Use"`
|
||||
DeletedBytesCleanedUpTotal float64 `perflib:"Deleted Bytes Cleaned Up"`
|
||||
DeletedBytesGeneratedTotal float64 `perflib:"Deleted Bytes Generated"`
|
||||
DeletedFilesCleanedUpTotal float64 `perflib:"Deleted Files Cleaned Up"`
|
||||
DeletedFilesGeneratedTotal float64 `perflib:"Deleted Files Generated"`
|
||||
FileInstallsRetriedTotal float64 `perflib:"File Installs Retried"`
|
||||
FileInstallsSucceededTotal float64 `perflib:"File Installs Succeeded"`
|
||||
FilesReceivedTotal float64 `perflib:"Total Files Received"`
|
||||
RDCBytesReceivedTotal float64 `perflib:"RDC Bytes Received"`
|
||||
RDCCompressedSizeOfFilesReceivedTotal float64 `perflib:"RDC Compressed Size of Files Received"`
|
||||
RDCNumberofFilesReceivedTotal float64 `perflib:"RDC Number of Files Received"`
|
||||
RDCSizeOfFilesReceivedTotal float64 `perflib:"RDC Size of Files Received"`
|
||||
SizeOfFilesReceivedTotal float64 `perflib:"Size of Files Received"`
|
||||
StagingSpaceInUse float64 `perflib:"Staging Space In Use"`
|
||||
StagingBytesCleanedUpTotal float64 `perflib:"Staging Bytes Cleaned Up"`
|
||||
StagingBytesGeneratedTotal float64 `perflib:"Staging Bytes Generated"`
|
||||
StagingFilesCleanedUpTotal float64 `perflib:"Staging Files Cleaned Up"`
|
||||
StagingFilesGeneratedTotal float64 `perflib:"Staging Files Generated"`
|
||||
UpdatesDroppedTotal float64 `perflib:"Updates Dropped"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectFolder(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
var dst []perflibDFSRFolder
|
||||
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replicated Folders"], &dst, logger); err != nil {
|
||||
return err
|
||||
func (c *Collector) collectPDHFolder(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorFolder.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DFS Replicated Folders metrics: %w", err)
|
||||
}
|
||||
|
||||
for _, folder := range dst {
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for DFS Replicated Folders returned empty result set")
|
||||
}
|
||||
|
||||
for name, folder := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderBandwidthSavingsUsingDFSReplicationTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.BandwidthSavingsUsingDFSReplicationTotal,
|
||||
folder.Name,
|
||||
folder[bandwidthSavingsUsingDFSReplicationTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.CompressedSizeOfFilesReceivedTotal,
|
||||
folder.Name,
|
||||
folder[compressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictBytesCleanedupTotal,
|
||||
c.folderConflictBytesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.ConflictBytesCleanedupTotal,
|
||||
folder.Name,
|
||||
folder[conflictBytesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictBytesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.ConflictBytesGeneratedTotal,
|
||||
folder.Name,
|
||||
folder[conflictBytesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictFilesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.ConflictFilesCleanedUpTotal,
|
||||
folder.Name,
|
||||
folder[conflictFilesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictFilesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.ConflictFilesGeneratedTotal,
|
||||
folder.Name,
|
||||
folder[conflictFilesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictfolderCleanupsCompletedTotal,
|
||||
c.folderConflictFolderCleanupsCompletedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.ConflictFolderCleanupsCompletedTotal,
|
||||
folder.Name,
|
||||
folder[conflictFolderCleanupsCompletedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderConflictSpaceInUse,
|
||||
prometheus.GaugeValue,
|
||||
folder.ConflictSpaceInUse,
|
||||
folder.Name,
|
||||
folder[conflictSpaceInUse].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedSpaceInUse,
|
||||
prometheus.GaugeValue,
|
||||
folder.DeletedSpaceInUse,
|
||||
folder.Name,
|
||||
folder[deletedSpaceInUse].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedBytesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.DeletedBytesCleanedUpTotal,
|
||||
folder.Name,
|
||||
folder[deletedBytesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedBytesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.DeletedBytesGeneratedTotal,
|
||||
folder.Name,
|
||||
folder[deletedBytesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedFilesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.DeletedFilesCleanedUpTotal,
|
||||
folder.Name,
|
||||
folder[deletedFilesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderDeletedFilesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.DeletedFilesGeneratedTotal,
|
||||
folder.Name,
|
||||
folder[deletedFilesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderFileInstallsRetriedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.FileInstallsRetriedTotal,
|
||||
folder.Name,
|
||||
folder[fileInstallsRetriedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderFileInstallsSucceededTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.FileInstallsSucceededTotal,
|
||||
folder.Name,
|
||||
folder[fileInstallsSucceededTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.FilesReceivedTotal,
|
||||
folder.Name,
|
||||
folder[filesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCBytesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.RDCBytesReceivedTotal,
|
||||
folder.Name,
|
||||
folder[rdcBytesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCCompressedSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.RDCCompressedSizeOfFilesReceivedTotal,
|
||||
folder.Name,
|
||||
folder[rdcCompressedSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCNumberofFilesReceivedTotal,
|
||||
c.folderRDCNumberOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.RDCNumberofFilesReceivedTotal,
|
||||
folder.Name,
|
||||
folder[rdcNumberOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderRDCSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.RDCSizeOfFilesReceivedTotal,
|
||||
folder.Name,
|
||||
folder[rdcSizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderSizeOfFilesReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.SizeOfFilesReceivedTotal,
|
||||
folder.Name,
|
||||
folder[sizeOfFilesReceivedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingSpaceInUse,
|
||||
prometheus.GaugeValue,
|
||||
folder.StagingSpaceInUse,
|
||||
folder.Name,
|
||||
folder[stagingSpaceInUse].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingBytesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.StagingBytesCleanedUpTotal,
|
||||
folder.Name,
|
||||
folder[stagingBytesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingBytesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.StagingBytesGeneratedTotal,
|
||||
folder.Name,
|
||||
folder[stagingBytesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingFilesCleanedUpTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.StagingFilesCleanedUpTotal,
|
||||
folder.Name,
|
||||
folder[stagingFilesCleanedUpTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderStagingFilesGeneratedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.StagingFilesGeneratedTotal,
|
||||
folder.Name,
|
||||
folder[stagingFilesGeneratedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.folderUpdatesDroppedTotal,
|
||||
prometheus.CounterValue,
|
||||
folder.UpdatesDroppedTotal,
|
||||
folder.Name,
|
||||
folder[updatesDroppedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// perflibDFSRVolume Perflib: "DFS Replication Service Volumes".
|
||||
type perflibDFSRVolume struct {
|
||||
Name string
|
||||
|
||||
DatabaseCommitsTotal float64 `perflib:"Database Commits"`
|
||||
DatabaseLookupsTotal float64 `perflib:"Database Lookups"`
|
||||
USNJournalRecordsReadTotal float64 `perflib:"USN Journal Records Read"`
|
||||
USNJournalRecordsAcceptedTotal float64 `perflib:"USN Journal Records Accepted"`
|
||||
USNJournalUnreadPercentage float64 `perflib:"USN Journal Records Unread Percentage"`
|
||||
}
|
||||
|
||||
func (c *Collector) collectVolume(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
var dst []perflibDFSRVolume
|
||||
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DFS Replication Service Volumes"], &dst, logger); err != nil {
|
||||
return err
|
||||
func (c *Collector) collectPDHVolume(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorVolume.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DFS Replication Volumes metrics: %w", err)
|
||||
}
|
||||
|
||||
for _, volume := range dst {
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for DFS Replication Volumes returned empty result set")
|
||||
}
|
||||
|
||||
for name, volume := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeDatabaseLookupsTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.DatabaseLookupsTotal,
|
||||
volume.Name,
|
||||
volume[databaseLookupsTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeDatabaseCommitsTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.DatabaseCommitsTotal,
|
||||
volume.Name,
|
||||
volume[databaseCommitsTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeUSNJournalRecordsAcceptedTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.USNJournalRecordsAcceptedTotal,
|
||||
volume.Name,
|
||||
volume[usnJournalRecordsAcceptedTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeUSNJournalRecordsReadTotal,
|
||||
prometheus.CounterValue,
|
||||
volume.USNJournalRecordsReadTotal,
|
||||
volume.Name,
|
||||
volume[usnJournalRecordsReadTotal].FirstValue,
|
||||
name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.volumeUSNJournalUnreadPercentage,
|
||||
prometheus.GaugeValue,
|
||||
volume.USNJournalUnreadPercentage,
|
||||
volume.Name,
|
||||
volume[usnJournalUnreadPercentage].FirstValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
14
internal/collector/dfsr/dfsr_test.go
Normal file
14
internal/collector/dfsr/dfsr_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package dfsr_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/dfsr"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, dfsr.Name, dfsr.NewWithFlags)
|
||||
}
|
||||
31
internal/collector/dhcp/const.go
Normal file
31
internal/collector/dhcp/const.go
Normal file
@@ -0,0 +1,31 @@
|
||||
//go:build windows
|
||||
|
||||
package dhcp
|
||||
|
||||
const (
|
||||
acksTotal = "Acks/sec"
|
||||
activeQueueLength = "Active Queue Length"
|
||||
conflictCheckQueueLength = "Conflict Check Queue Length"
|
||||
declinesTotal = "Declines/sec"
|
||||
deniedDueToMatch = "Denied due to match."
|
||||
deniedDueToNonMatch = "Denied due to match."
|
||||
discoversTotal = "Discovers/sec"
|
||||
duplicatesDroppedTotal = "Duplicates Dropped/sec"
|
||||
failoverBndAckReceivedTotal = "Failover: BndAck received/sec."
|
||||
failoverBndAckSentTotal = "Failover: BndAck sent/sec."
|
||||
failoverBndUpdDropped = "Failover: BndUpd Dropped."
|
||||
failoverBndUpdPendingOutboundQueue = "Failover: BndUpd pending in outbound queue."
|
||||
failoverBndUpdReceivedTotal = "Failover: BndUpd received/sec."
|
||||
failoverBndUpdSentTotal = "Failover: BndUpd sent/sec."
|
||||
failoverTransitionsCommunicationInterruptedState = "Failover: Transitions to COMMUNICATION-INTERRUPTED state."
|
||||
failoverTransitionsPartnerDownState = "Failover: Transitions to PARTNER-DOWN state."
|
||||
failoverTransitionsRecoverState = "Failover: Transitions to RECOVER state."
|
||||
informsTotal = "Informs/sec"
|
||||
nacksTotal = "Nacks/sec"
|
||||
offerQueueLength = "Offer Queue Length"
|
||||
offersTotal = "Offers/sec"
|
||||
packetsExpiredTotal = "Packets Expired/sec"
|
||||
packetsReceivedTotal = "Packets Received/sec"
|
||||
releasesTotal = "Releases/sec"
|
||||
requestsTotal = "Requests/sec"
|
||||
)
|
||||
@@ -3,13 +3,15 @@
|
||||
package dhcp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/perflib"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "dhcp"
|
||||
@@ -22,6 +24,8 @@ var ConfigDefaults = Config{}
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollector *perfdata.Collector
|
||||
|
||||
acksTotal *prometheus.Desc
|
||||
activeQueueLength *prometheus.Desc
|
||||
conflictCheckQueueLength *prometheus.Desc
|
||||
@@ -30,12 +34,12 @@ type Collector struct {
|
||||
deniedDueToNonMatch *prometheus.Desc
|
||||
discoversTotal *prometheus.Desc
|
||||
duplicatesDroppedTotal *prometheus.Desc
|
||||
failoverBndackReceivedTotal *prometheus.Desc
|
||||
failoverBndackSentTotal *prometheus.Desc
|
||||
failoverBndupdDropped *prometheus.Desc
|
||||
failoverBndupdPendingOutboundQueue *prometheus.Desc
|
||||
failoverBndupdReceivedTotal *prometheus.Desc
|
||||
failoverBndupdSentTotal *prometheus.Desc
|
||||
failoverBndAckReceivedTotal *prometheus.Desc
|
||||
failoverBndAckSentTotal *prometheus.Desc
|
||||
failoverBndUpdDropped *prometheus.Desc
|
||||
failoverBndUpdPendingOutboundQueue *prometheus.Desc
|
||||
failoverBndUpdReceivedTotal *prometheus.Desc
|
||||
failoverBndUpdSentTotal *prometheus.Desc
|
||||
failoverTransitionsCommunicationInterruptedState *prometheus.Desc
|
||||
failoverTransitionsPartnerDownState *prometheus.Desc
|
||||
failoverTransitionsRecoverState *prometheus.Desc
|
||||
@@ -69,15 +73,46 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{"DHCP Server"}, nil
|
||||
}
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollector.Close()
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = perfdata.NewCollector("DHCP Server", perfdata.InstanceAll, []string{
|
||||
acksTotal,
|
||||
activeQueueLength,
|
||||
conflictCheckQueueLength,
|
||||
declinesTotal,
|
||||
deniedDueToMatch,
|
||||
deniedDueToNonMatch,
|
||||
discoversTotal,
|
||||
duplicatesDroppedTotal,
|
||||
failoverBndAckReceivedTotal,
|
||||
failoverBndAckSentTotal,
|
||||
failoverBndUpdDropped,
|
||||
failoverBndUpdPendingOutboundQueue,
|
||||
failoverBndUpdReceivedTotal,
|
||||
failoverBndUpdSentTotal,
|
||||
failoverTransitionsCommunicationInterruptedState,
|
||||
failoverTransitionsPartnerDownState,
|
||||
failoverTransitionsRecoverState,
|
||||
informsTotal,
|
||||
nacksTotal,
|
||||
offerQueueLength,
|
||||
offersTotal,
|
||||
packetsExpiredTotal,
|
||||
packetsReceivedTotal,
|
||||
releasesTotal,
|
||||
requestsTotal,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DHCP Server collector: %w", err)
|
||||
}
|
||||
|
||||
c.packetsReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "packets_received_total"),
|
||||
"Total number of packets received by the DHCP server (PacketsReceivedTotal)",
|
||||
@@ -174,31 +209,31 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdSentTotal = prometheus.NewDesc(
|
||||
c.failoverBndUpdSentTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_sent_total"),
|
||||
"Number of DHCP fail over Binding Update messages sent (FailoverBndupdSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdReceivedTotal = prometheus.NewDesc(
|
||||
c.failoverBndUpdReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_received_total"),
|
||||
"Number of DHCP fail over Binding Update messages received (FailoverBndupdReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndackSentTotal = prometheus.NewDesc(
|
||||
c.failoverBndAckSentTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_sent_total"),
|
||||
"Number of DHCP fail over Binding Ack messages sent (FailoverBndackSentTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndackReceivedTotal = prometheus.NewDesc(
|
||||
c.failoverBndAckReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndack_received_total"),
|
||||
"Number of DHCP fail over Binding Ack messages received (FailoverBndackReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdPendingOutboundQueue = prometheus.NewDesc(
|
||||
c.failoverBndUpdPendingOutboundQueue = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_pending_in_outbound_queue"),
|
||||
"Number of pending outbound DHCP fail over Binding Update messages (FailoverBndupdPendingOutboundQueue)",
|
||||
nil,
|
||||
@@ -222,7 +257,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndupdDropped = prometheus.NewDesc(
|
||||
c.failoverBndUpdDropped = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_dropped_total"),
|
||||
"Total number of DHCP fail over Binding Updates dropped (FailoverBndupdDropped)",
|
||||
nil,
|
||||
@@ -232,194 +267,165 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// represents perflib metrics from the DHCP Server class.
|
||||
// While the name of a number of perflib metrics would indicate a rate is being returned (E.G. Packets Received/sec),
|
||||
// perflib instead returns a counter, hence the "Total" suffix in some of the variable names.
|
||||
type dhcpPerf struct {
|
||||
PacketsReceivedTotal float64 `perflib:"Packets Received/sec"`
|
||||
DuplicatesDroppedTotal float64 `perflib:"Duplicates Dropped/sec"`
|
||||
PacketsExpiredTotal float64 `perflib:"Packets Expired/sec"`
|
||||
ActiveQueueLength float64 `perflib:"Active Queue Length"`
|
||||
ConflictCheckQueueLength float64 `perflib:"Conflict Check Queue Length"`
|
||||
DiscoversTotal float64 `perflib:"Discovers/sec"`
|
||||
OffersTotal float64 `perflib:"Offers/sec"`
|
||||
RequestsTotal float64 `perflib:"Requests/sec"`
|
||||
InformsTotal float64 `perflib:"Informs/sec"`
|
||||
AcksTotal float64 `perflib:"Acks/sec"`
|
||||
NacksTotal float64 `perflib:"Nacks/sec"`
|
||||
DeclinesTotal float64 `perflib:"Declines/sec"`
|
||||
ReleasesTotal float64 `perflib:"Releases/sec"`
|
||||
DeniedDueToMatch float64 `perflib:"Denied due to match."`
|
||||
DeniedDueToNonMatch float64 `perflib:"Denied due to match."`
|
||||
OfferQueueLength float64 `perflib:"Offer Queue Length"`
|
||||
FailoverBndupdSentTotal float64 `perflib:"Failover: BndUpd sent/sec."`
|
||||
FailoverBndupdReceivedTotal float64 `perflib:"Failover: BndUpd received/sec."`
|
||||
FailoverBndackSentTotal float64 `perflib:"Failover: BndAck sent/sec."`
|
||||
FailoverBndackReceivedTotal float64 `perflib:"Failover: BndAck received/sec."`
|
||||
FailoverBndupdPendingOutboundQueue float64 `perflib:"Failover: BndUpd pending in outbound queue."`
|
||||
FailoverTransitionsCommunicationinterruptedState float64 `perflib:"Failover: Transitions to COMMUNICATION-INTERRUPTED state."`
|
||||
FailoverTransitionsPartnerdownState float64 `perflib:"Failover: Transitions to PARTNER-DOWN state."`
|
||||
FailoverTransitionsRecoverState float64 `perflib:"Failover: Transitions to RECOVER state."`
|
||||
FailoverBndupdDropped float64 `perflib:"Failover: BndUpd Dropped."`
|
||||
}
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DHCP Server metrics: %w", err)
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ctx *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
var dhcpPerfs []dhcpPerf
|
||||
|
||||
if err := perflib.UnmarshalObject(ctx.PerfObjects["DHCP Server"], &dhcpPerfs, logger); err != nil {
|
||||
return err
|
||||
data, ok := perfData[perfdata.EmptyInstance]
|
||||
if !ok {
|
||||
return errors.New("perflib query for DHCP Server returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.packetsReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].PacketsReceivedTotal,
|
||||
data[packetsReceivedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.duplicatesDroppedTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].DuplicatesDroppedTotal,
|
||||
data[duplicatesDroppedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.packetsExpiredTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].PacketsExpiredTotal,
|
||||
data[packetsExpiredTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
dhcpPerfs[0].ActiveQueueLength,
|
||||
data[activeQueueLength].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.conflictCheckQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
dhcpPerfs[0].ConflictCheckQueueLength,
|
||||
data[conflictCheckQueueLength].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.discoversTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].DiscoversTotal,
|
||||
data[discoversTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.offersTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].OffersTotal,
|
||||
data[offersTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestsTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].RequestsTotal,
|
||||
data[requestsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.informsTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].InformsTotal,
|
||||
data[informsTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.acksTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].AcksTotal,
|
||||
data[acksTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.nACKsTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].NacksTotal,
|
||||
data[nacksTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.declinesTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].DeclinesTotal,
|
||||
data[declinesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.releasesTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].ReleasesTotal,
|
||||
data[releasesTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.offerQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
dhcpPerfs[0].OfferQueueLength,
|
||||
data[offerQueueLength].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.deniedDueToMatch,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].DeniedDueToMatch,
|
||||
data[deniedDueToMatch].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.deniedDueToNonMatch,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].DeniedDueToNonMatch,
|
||||
data[deniedDueToNonMatch].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdSentTotal,
|
||||
c.failoverBndUpdSentTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndupdSentTotal,
|
||||
data[failoverBndUpdSentTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdReceivedTotal,
|
||||
c.failoverBndUpdReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndupdReceivedTotal,
|
||||
data[failoverBndUpdReceivedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndackSentTotal,
|
||||
c.failoverBndAckSentTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndackSentTotal,
|
||||
data[failoverBndAckSentTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndackReceivedTotal,
|
||||
c.failoverBndAckReceivedTotal,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndackReceivedTotal,
|
||||
data[failoverBndAckReceivedTotal].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdPendingOutboundQueue,
|
||||
c.failoverBndUpdPendingOutboundQueue,
|
||||
prometheus.GaugeValue,
|
||||
dhcpPerfs[0].FailoverBndupdPendingOutboundQueue,
|
||||
data[failoverBndUpdPendingOutboundQueue].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsCommunicationInterruptedState,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverTransitionsCommunicationinterruptedState,
|
||||
data[failoverTransitionsCommunicationInterruptedState].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsPartnerDownState,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverTransitionsPartnerdownState,
|
||||
data[failoverTransitionsPartnerDownState].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverTransitionsRecoverState,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverTransitionsRecoverState,
|
||||
data[failoverTransitionsRecoverState].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.failoverBndupdDropped,
|
||||
c.failoverBndUpdDropped,
|
||||
prometheus.CounterValue,
|
||||
dhcpPerfs[0].FailoverBndupdDropped,
|
||||
data[failoverBndUpdDropped].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
14
internal/collector/dhcp/dhcp_test.go
Normal file
14
internal/collector/dhcp/dhcp_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package dhcp_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/dhcp"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, dhcp.Name, dhcp.NewWithFlags)
|
||||
}
|
||||
@@ -4,19 +4,17 @@ package diskdrive
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const (
|
||||
Name = "diskdrive"
|
||||
win32DiskQuery = "SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive"
|
||||
)
|
||||
const Name = "diskdrive"
|
||||
|
||||
type Config struct{}
|
||||
|
||||
@@ -25,7 +23,8 @@ var ConfigDefaults = Config{}
|
||||
// A Collector is a Prometheus Collector for a few WMI metrics in Win32_DiskDrive.
|
||||
type Collector struct {
|
||||
config Config
|
||||
wmiClient *wmi.Client
|
||||
miSession *mi.Session
|
||||
miQuery mi.Query
|
||||
|
||||
availability *prometheus.Desc
|
||||
diskInfo *prometheus.Desc
|
||||
@@ -54,20 +53,23 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
|
||||
return errors.New("wmiClient or SWbemServicesClient is nil")
|
||||
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
|
||||
if miSession == nil {
|
||||
return errors.New("miSession is nil")
|
||||
}
|
||||
|
||||
c.wmiClient = wmiClient
|
||||
miQuery, err := mi.NewQuery("SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
c.miQuery = miQuery
|
||||
c.miSession = miSession
|
||||
|
||||
c.diskInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||
"General drive information",
|
||||
@@ -107,15 +109,15 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type win32_DiskDrive struct {
|
||||
DeviceID string
|
||||
Model string
|
||||
Size uint64
|
||||
Name string
|
||||
Caption string
|
||||
Partitions uint32
|
||||
Status string
|
||||
Availability uint16
|
||||
type diskDrive struct {
|
||||
DeviceID string `mi:"DeviceID"`
|
||||
Model string `mi:"Model"`
|
||||
Size uint64 `mi:"Size"`
|
||||
Name string `mi:"Name"`
|
||||
Caption string `mi:"Caption"`
|
||||
Partitions uint32 `mi:"Partitions"`
|
||||
Status string `mi:"Status"`
|
||||
Availability uint16 `mi:"Availability"`
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -160,24 +162,10 @@ var (
|
||||
)
|
||||
|
||||
// Collect sends the metric values for each metric to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
logger.Error("failed collecting disk_drive_info metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []win32_DiskDrive
|
||||
|
||||
if err := c.wmiClient.Query(win32DiskQuery, &dst); err != nil {
|
||||
return err
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []diskDrive
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, c.miQuery); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
if len(dst) == 0 {
|
||||
@@ -185,14 +173,16 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
}
|
||||
|
||||
for _, disk := range dst {
|
||||
distName := strings.Trim(disk.Name, `\.`)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.diskInfo,
|
||||
prometheus.GaugeValue,
|
||||
1.0,
|
||||
strings.Trim(disk.DeviceID, "\\.\\"), //nolint:staticcheck
|
||||
strings.Trim(disk.DeviceID, `\.`),
|
||||
strings.TrimRight(disk.Model, " "),
|
||||
strings.TrimRight(disk.Caption, " "),
|
||||
strings.TrimRight(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||
distName,
|
||||
)
|
||||
|
||||
for _, status := range allDiskStatus {
|
||||
@@ -205,7 +195,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
c.status,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||
distName,
|
||||
status,
|
||||
)
|
||||
}
|
||||
@@ -214,14 +204,14 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
c.size,
|
||||
prometheus.GaugeValue,
|
||||
float64(disk.Size),
|
||||
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||
distName,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.partitions,
|
||||
prometheus.GaugeValue,
|
||||
float64(disk.Partitions),
|
||||
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||
distName,
|
||||
)
|
||||
|
||||
for availNum, val := range availMap {
|
||||
@@ -233,7 +223,7 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
c.availability,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
strings.Trim(disk.Name, "\\.\\"), //nolint:staticcheck
|
||||
distName,
|
||||
val,
|
||||
)
|
||||
}
|
||||
14
internal/collector/diskdrive/diskdrive_test.go
Normal file
14
internal/collector/diskdrive/diskdrive_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package diskdrive_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/diskdrive"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, diskdrive.Name, diskdrive.NewWithFlags)
|
||||
}
|
||||
94
internal/collector/dns/const.go
Normal file
94
internal/collector/dns/const.go
Normal file
@@ -0,0 +1,94 @@
|
||||
//go:build windows
|
||||
|
||||
package dns
|
||||
|
||||
const (
|
||||
_ = "% User Time"
|
||||
_ = "176"
|
||||
_ = "Async Fast Reads/sec"
|
||||
axfrRequestReceived = "AXFR Request Received"
|
||||
axfrRequestSent = "AXFR Request Sent"
|
||||
axfrResponseReceived = "AXFR Response Received"
|
||||
axfrSuccessReceived = "AXFR Success Received"
|
||||
axfrSuccessSent = "AXFR Success Sent"
|
||||
cachingMemory = "Caching Memory"
|
||||
_ = "Data Flush Pages/sec"
|
||||
_ = "Data Flushes/sec"
|
||||
databaseNodeMemory = "Database Node Memory"
|
||||
dynamicUpdateNoOperation = "Dynamic Update NoOperation"
|
||||
_ = "Dynamic Update NoOperation/sec"
|
||||
dynamicUpdateQueued = "Dynamic Update Queued"
|
||||
_ = "Dynamic Update Received"
|
||||
_ = "Dynamic Update Received/sec"
|
||||
dynamicUpdateRejected = "Dynamic Update Rejected"
|
||||
dynamicUpdateTimeOuts = "Dynamic Update TimeOuts"
|
||||
dynamicUpdateWrittenToDatabase = "Dynamic Update Written to Database"
|
||||
_ = "Dynamic Update Written to Database/sec"
|
||||
_ = "Enumerations Server/sec"
|
||||
_ = "Fast Read Not Possibles/sec"
|
||||
_ = "Fast Read Resource Misses/sec"
|
||||
ixfrRequestReceived = "IXFR Request Received"
|
||||
ixfrRequestSent = "IXFR Request Sent"
|
||||
ixfrResponseReceived = "IXFR Response Received"
|
||||
_ = "IXFR Success Received"
|
||||
ixfrSuccessSent = "IXFR Success Sent"
|
||||
ixfrTCPSuccessReceived = "IXFR TCP Success Received"
|
||||
ixfrUDPSuccessReceived = "IXFR UDP Success Received"
|
||||
_ = "Lazy Write Flushes/sec"
|
||||
_ = "Lazy Write Pages/sec"
|
||||
_ = "Level 2 TLB Fills/sec"
|
||||
nbStatMemory = "Nbstat Memory"
|
||||
notifyReceived = "Notify Received"
|
||||
notifySent = "Notify Sent"
|
||||
_ = "Query Dropped Bad Socket"
|
||||
_ = "Query Dropped Bad Socket/sec"
|
||||
_ = "Query Dropped By Policy"
|
||||
_ = "Query Dropped By Policy/sec"
|
||||
_ = "Query Dropped By Response Rate Limiting"
|
||||
_ = "Query Dropped By Response Rate Limiting/sec"
|
||||
_ = "Query Dropped Send"
|
||||
_ = "Query Dropped Send/sec"
|
||||
_ = "Query Dropped Total"
|
||||
_ = "Query Dropped Total/sec"
|
||||
recordFlowMemory = "Record Flow Memory"
|
||||
recursiveQueries = "Recursive Queries"
|
||||
_ = "Recursive Queries/sec"
|
||||
recursiveQueryFailure = "Recursive Query Failure"
|
||||
_ = "Recursive Query Failure/sec"
|
||||
_ = "Recursive Send TimeOuts"
|
||||
recursiveSendTimeOuts = "Recursive TimeOut/sec"
|
||||
_ = "Responses Suppressed"
|
||||
_ = "Responses Suppressed/sec"
|
||||
secureUpdateFailure = "Secure Update Failure"
|
||||
secureUpdateReceived = "Secure Update Received"
|
||||
_ = "Secure Update Received/sec"
|
||||
tcpMessageMemory = "TCP Message Memory"
|
||||
tcpQueryReceived = "TCP Query Received"
|
||||
_ = "TCP Query Received/sec"
|
||||
tcpResponseSent = "TCP Response Sent"
|
||||
_ = "TCP Response Sent/sec"
|
||||
_ = "Total Query Received"
|
||||
_ = "Total Query Received/sec"
|
||||
_ = "Total Remote Inflight Queries"
|
||||
_ = "Total Response Sent"
|
||||
_ = "Total Response Sent/sec"
|
||||
udpMessageMemory = "UDP Message Memory"
|
||||
udpQueryReceived = "UDP Query Received"
|
||||
_ = "UDP Query Received/sec"
|
||||
udpResponseSent = "UDP Response Sent"
|
||||
_ = "UDP Response Sent/sec"
|
||||
unmatchedResponsesReceived = "Unmatched Responses Received"
|
||||
_ = "Virtual Bytes"
|
||||
winsLookupReceived = "WINS Lookup Received"
|
||||
_ = "WINS Lookup Received/sec"
|
||||
winsResponseSent = "WINS Response Sent"
|
||||
_ = "WINS Response Sent/sec"
|
||||
winsReverseLookupReceived = "WINS Reverse Lookup Received"
|
||||
_ = "WINS Reverse Lookup Received/sec"
|
||||
winsReverseResponseSent = "WINS Reverse Response Sent"
|
||||
_ = "WINS Reverse Response Sent/sec"
|
||||
zoneTransferFailure = "Zone Transfer Failure"
|
||||
zoneTransferSOARequestSent = "Zone Transfer Request Received"
|
||||
_ = "Zone Transfer SOA Request Sent"
|
||||
_ = "Zone Transfer Success"
|
||||
)
|
||||
@@ -4,12 +4,14 @@ package dns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "dns"
|
||||
@@ -20,8 +22,9 @@ var ConfigDefaults = Config{}
|
||||
|
||||
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_DNS_DNS metrics.
|
||||
type Collector struct {
|
||||
config Config
|
||||
wmiClient *wmi.Client
|
||||
config Config
|
||||
|
||||
perfDataCollector *perfdata.Collector
|
||||
|
||||
dynamicUpdatesFailures *prometheus.Desc
|
||||
dynamicUpdatesQueued *prometheus.Desc
|
||||
@@ -67,20 +70,60 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollector.Close()
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
|
||||
return errors.New("wmiClient or SWbemServicesClient is nil")
|
||||
}
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
var err error
|
||||
|
||||
c.wmiClient = wmiClient
|
||||
c.perfDataCollector, err = perfdata.NewCollector("DNS", perfdata.InstanceAll, []string{
|
||||
axfrRequestReceived,
|
||||
axfrRequestSent,
|
||||
axfrResponseReceived,
|
||||
axfrSuccessReceived,
|
||||
axfrSuccessSent,
|
||||
cachingMemory,
|
||||
databaseNodeMemory,
|
||||
dynamicUpdateNoOperation,
|
||||
dynamicUpdateQueued,
|
||||
dynamicUpdateRejected,
|
||||
dynamicUpdateTimeOuts,
|
||||
dynamicUpdateWrittenToDatabase,
|
||||
ixfrRequestReceived,
|
||||
ixfrRequestSent,
|
||||
ixfrResponseReceived,
|
||||
ixfrSuccessSent,
|
||||
ixfrTCPSuccessReceived,
|
||||
ixfrUDPSuccessReceived,
|
||||
nbStatMemory,
|
||||
notifyReceived,
|
||||
notifySent,
|
||||
recordFlowMemory,
|
||||
recursiveQueries,
|
||||
recursiveQueryFailure,
|
||||
recursiveSendTimeOuts,
|
||||
secureUpdateFailure,
|
||||
secureUpdateReceived,
|
||||
tcpMessageMemory,
|
||||
tcpQueryReceived,
|
||||
tcpResponseSent,
|
||||
udpMessageMemory,
|
||||
udpQueryReceived,
|
||||
udpResponseSent,
|
||||
unmatchedResponsesReceived,
|
||||
winsLookupReceived,
|
||||
winsResponseSent,
|
||||
winsReverseLookupReceived,
|
||||
winsReverseResponseSent,
|
||||
zoneTransferFailure,
|
||||
zoneTransferSOARequestSent,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DNS collector: %w", err)
|
||||
}
|
||||
|
||||
c.zoneTransferRequestsReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
|
||||
@@ -220,138 +263,80 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
logger.Error("failed collecting dns metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollector.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DNS metrics: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_PerfRawData_DNS_DNS docs:
|
||||
// - https://msdn.microsoft.com/en-us/library/ms803992.aspx?f=255&MSPPError=-2147217396
|
||||
// - https://technet.microsoft.com/en-us/library/cc977686.aspx
|
||||
type Win32_PerfRawData_DNS_DNS struct {
|
||||
AXFRRequestReceived uint32
|
||||
AXFRRequestSent uint32
|
||||
AXFRResponseReceived uint32
|
||||
AXFRSuccessReceived uint32
|
||||
AXFRSuccessSent uint32
|
||||
CachingMemory uint32
|
||||
DatabaseNodeMemory uint32
|
||||
DynamicUpdateNoOperation uint32
|
||||
DynamicUpdateQueued uint32
|
||||
DynamicUpdateRejected uint32
|
||||
DynamicUpdateTimeOuts uint32
|
||||
DynamicUpdateWrittentoDatabase uint32
|
||||
IXFRRequestReceived uint32
|
||||
IXFRRequestSent uint32
|
||||
IXFRResponseReceived uint32
|
||||
IXFRSuccessSent uint32
|
||||
IXFRTCPSuccessReceived uint32
|
||||
IXFRUDPSuccessReceived uint32
|
||||
NbstatMemory uint32
|
||||
NotifyReceived uint32
|
||||
NotifySent uint32
|
||||
RecordFlowMemory uint32
|
||||
RecursiveQueries uint32
|
||||
RecursiveQueryFailure uint32
|
||||
RecursiveSendTimeOuts uint32
|
||||
SecureUpdateFailure uint32
|
||||
SecureUpdateReceived uint32
|
||||
TCPMessageMemory uint32
|
||||
TCPQueryReceived uint32
|
||||
TCPResponseSent uint32
|
||||
UDPMessageMemory uint32
|
||||
UDPQueryReceived uint32
|
||||
UDPResponseSent uint32
|
||||
UnmatchedResponsesReceived uint32
|
||||
WINSLookupReceived uint32
|
||||
WINSResponseSent uint32
|
||||
WINSReverseLookupReceived uint32
|
||||
WINSReverseResponseSent uint32
|
||||
ZoneTransferFailure uint32
|
||||
ZoneTransferSOARequestSent uint32
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_DNS_DNS
|
||||
if err := c.wmiClient.Query("SELECT * FROM Win32_PerfRawData_DNS_DNS", &dst); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(dst) == 0 {
|
||||
return errors.New("WMI query returned empty result set")
|
||||
data, ok := perfData[perfdata.EmptyInstance]
|
||||
if !ok {
|
||||
return errors.New("perflib query for DNS returned empty result set")
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRRequestReceived),
|
||||
data[axfrRequestReceived].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRRequestReceived),
|
||||
data[ixfrRequestReceived].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRRequestSent),
|
||||
data[axfrRequestSent].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRRequestSent),
|
||||
data[ixfrRequestSent].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].ZoneTransferSOARequestSent),
|
||||
data[zoneTransferSOARequestSent].FirstValue,
|
||||
"soa",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRResponseReceived),
|
||||
data[axfrResponseReceived].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRResponseReceived),
|
||||
data[ixfrResponseReceived].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRSuccessReceived),
|
||||
data[axfrSuccessReceived].FirstValue,
|
||||
"full",
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRTCPSuccessReceived),
|
||||
data[ixfrTCPSuccessReceived].FirstValue,
|
||||
"incremental",
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRTCPSuccessReceived),
|
||||
data[ixfrTCPSuccessReceived].FirstValue,
|
||||
"incremental",
|
||||
"udp",
|
||||
)
|
||||
@@ -359,183 +344,183 @@ func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].AXFRSuccessSent),
|
||||
data[axfrSuccessSent].FirstValue,
|
||||
"full",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessSent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].IXFRSuccessSent),
|
||||
data[ixfrSuccessSent].FirstValue,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].ZoneTransferFailure),
|
||||
data[zoneTransferFailure].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].CachingMemory),
|
||||
data[cachingMemory].FirstValue,
|
||||
"caching",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].DatabaseNodeMemory),
|
||||
data[databaseNodeMemory].FirstValue,
|
||||
"database_node",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].NbstatMemory),
|
||||
data[nbStatMemory].FirstValue,
|
||||
"nbstat",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].RecordFlowMemory),
|
||||
data[recordFlowMemory].FirstValue,
|
||||
"record_flow",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].TCPMessageMemory),
|
||||
data[tcpMessageMemory].FirstValue,
|
||||
"tcp_message",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].UDPMessageMemory),
|
||||
data[udpMessageMemory].FirstValue,
|
||||
"udp_message",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateNoOperation),
|
||||
data[dynamicUpdateNoOperation].FirstValue,
|
||||
"noop",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateWrittentoDatabase),
|
||||
data[dynamicUpdateWrittenToDatabase].FirstValue,
|
||||
"written",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesQueued,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].DynamicUpdateQueued),
|
||||
data[dynamicUpdateQueued].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateRejected),
|
||||
data[dynamicUpdateRejected].FirstValue,
|
||||
"rejected",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].DynamicUpdateTimeOuts),
|
||||
data[dynamicUpdateTimeOuts].FirstValue,
|
||||
"timeout",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.notifyReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].NotifyReceived),
|
||||
data[notifyReceived].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.notifySent,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].NotifySent),
|
||||
data[notifySent].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQueries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].RecursiveQueries),
|
||||
data[recursiveQueries].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQueryFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].RecursiveQueryFailure),
|
||||
data[recursiveQueryFailure].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQuerySendTimeouts,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].RecursiveSendTimeOuts),
|
||||
data[recursiveSendTimeOuts].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.queries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].TCPQueryReceived),
|
||||
data[tcpQueryReceived].FirstValue,
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.queries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].UDPQueryReceived),
|
||||
data[udpQueryReceived].FirstValue,
|
||||
"udp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.responses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].TCPResponseSent),
|
||||
data[tcpResponseSent].FirstValue,
|
||||
"tcp",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.responses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].UDPResponseSent),
|
||||
data[udpResponseSent].FirstValue,
|
||||
"udp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.unmatchedResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].UnmatchedResponsesReceived),
|
||||
data[unmatchedResponsesReceived].FirstValue,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsQueries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSLookupReceived),
|
||||
data[winsLookupReceived].FirstValue,
|
||||
"forward",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsQueries,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSReverseLookupReceived),
|
||||
data[winsReverseLookupReceived].FirstValue,
|
||||
"reverse",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsResponses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSResponseSent),
|
||||
data[winsResponseSent].FirstValue,
|
||||
"forward",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsResponses,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].WINSReverseResponseSent),
|
||||
data[winsReverseResponseSent].FirstValue,
|
||||
"reverse",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.secureUpdateFailures,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].SecureUpdateFailure),
|
||||
data[secureUpdateFailure].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.secureUpdateReceived,
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].SecureUpdateReceived),
|
||||
data[secureUpdateReceived].FirstValue,
|
||||
)
|
||||
|
||||
return nil
|
||||
14
internal/collector/dns/dns_test.go
Normal file
14
internal/collector/dns/dns_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package dns_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/dns"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, dns.Name, dns.NewWithFlags)
|
||||
}
|
||||
297
internal/collector/exchange/exchange.go
Normal file
297
internal/collector/exchange/exchange.go
Normal file
@@ -0,0 +1,297 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "exchange"
|
||||
|
||||
const (
|
||||
adAccessProcesses = "ADAccessProcesses"
|
||||
transportQueues = "TransportQueues"
|
||||
httpProxy = "HttpProxy"
|
||||
activeSync = "ActiveSync"
|
||||
availabilityService = "AvailabilityService"
|
||||
outlookWebAccess = "OutlookWebAccess"
|
||||
autoDiscover = "Autodiscover"
|
||||
workloadManagement = "WorkloadManagement"
|
||||
rpcClientAccess = "RpcClientAccess"
|
||||
mapiHttpEmsmdb = "MapiHttpEmsmdb"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
}
|
||||
|
||||
var ConfigDefaults = Config{
|
||||
CollectorsEnabled: []string{
|
||||
adAccessProcesses,
|
||||
transportQueues,
|
||||
httpProxy,
|
||||
activeSync,
|
||||
availabilityService,
|
||||
outlookWebAccess,
|
||||
autoDiscover,
|
||||
workloadManagement,
|
||||
rpcClientAccess,
|
||||
mapiHttpEmsmdb,
|
||||
},
|
||||
}
|
||||
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
perfDataCollectorADAccessProcesses *perfdata.Collector
|
||||
perfDataCollectorTransportQueues *perfdata.Collector
|
||||
perfDataCollectorHttpProxy *perfdata.Collector
|
||||
perfDataCollectorActiveSync *perfdata.Collector
|
||||
perfDataCollectorAvailabilityService *perfdata.Collector
|
||||
perfDataCollectorOWA *perfdata.Collector
|
||||
perfDataCollectorAutoDiscover *perfdata.Collector
|
||||
perfDataCollectorWorkloadManagementWorkloads *perfdata.Collector
|
||||
perfDataCollectorRpcClientAccess *perfdata.Collector
|
||||
perfDataCollectorMapiHttpEmsmdb *perfdata.Collector
|
||||
|
||||
activeMailboxDeliveryQueueLength *prometheus.Desc
|
||||
activeSyncRequestsPerSec *prometheus.Desc
|
||||
activeTasks *prometheus.Desc
|
||||
activeUserCount *prometheus.Desc
|
||||
activeUserCountMapiHttpEmsMDB *prometheus.Desc
|
||||
autoDiscoverRequestsPerSec *prometheus.Desc
|
||||
availabilityRequestsSec *prometheus.Desc
|
||||
averageAuthenticationLatency *prometheus.Desc
|
||||
averageCASProcessingLatency *prometheus.Desc
|
||||
completedTasks *prometheus.Desc
|
||||
connectionCount *prometheus.Desc
|
||||
currentUniqueUsers *prometheus.Desc
|
||||
externalActiveRemoteDeliveryQueueLength *prometheus.Desc
|
||||
externalLargestDeliveryQueueLength *prometheus.Desc
|
||||
internalActiveRemoteDeliveryQueueLength *prometheus.Desc
|
||||
internalLargestDeliveryQueueLength *prometheus.Desc
|
||||
isActive *prometheus.Desc
|
||||
ldapReadTime *prometheus.Desc
|
||||
ldapSearchTime *prometheus.Desc
|
||||
ldapTimeoutErrorsPerSec *prometheus.Desc
|
||||
ldapWriteTime *prometheus.Desc
|
||||
longRunningLDAPOperationsPerMin *prometheus.Desc
|
||||
mailboxServerLocatorAverageLatency *prometheus.Desc
|
||||
mailboxServerProxyFailureRate *prometheus.Desc
|
||||
outstandingProxyRequests *prometheus.Desc
|
||||
owaRequestsPerSec *prometheus.Desc
|
||||
pingCommandsPending *prometheus.Desc
|
||||
poisonQueueLength *prometheus.Desc
|
||||
proxyRequestsPerSec *prometheus.Desc
|
||||
queuedTasks *prometheus.Desc
|
||||
retryMailboxDeliveryQueueLength *prometheus.Desc
|
||||
rpcAveragedLatency *prometheus.Desc
|
||||
rpcOperationsPerSec *prometheus.Desc
|
||||
rpcRequests *prometheus.Desc
|
||||
syncCommandsPerSec *prometheus.Desc
|
||||
unreachableQueueLength *prometheus.Desc
|
||||
userCount *prometheus.Desc
|
||||
yieldedTasks *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
if config.CollectorsEnabled == nil {
|
||||
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
c.config.CollectorsEnabled = make([]string, 0)
|
||||
|
||||
var listAllCollectors bool
|
||||
|
||||
var collectorsEnabled string
|
||||
|
||||
app.Flag(
|
||||
"collector.exchange.list",
|
||||
"List the collectors along with their perflib object name/ids",
|
||||
).BoolVar(&listAllCollectors)
|
||||
|
||||
app.Flag(
|
||||
"collector.exchange.enabled",
|
||||
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||
).Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
|
||||
|
||||
app.PreAction(func(*kingpin.ParseContext) error {
|
||||
if listAllCollectors {
|
||||
collectorDesc := map[string]string{
|
||||
adAccessProcesses: "[19108] MSExchange ADAccess Processes",
|
||||
transportQueues: "[20524] MSExchangeTransport Queues",
|
||||
httpProxy: "[36934] MSExchange HttpProxy",
|
||||
activeSync: "[25138] MSExchange ActiveSync",
|
||||
availabilityService: "[24914] MSExchange Availability Service",
|
||||
outlookWebAccess: "[24618] MSExchange OWA",
|
||||
autoDiscover: "[29240] MSExchange Autodiscover",
|
||||
workloadManagement: "[19430] MSExchange WorkloadManagement Workloads",
|
||||
rpcClientAccess: "[29336] MSExchange RpcClientAccess",
|
||||
mapiHttpEmsmdb: "[26463] MSExchange MapiHttp Emsmdb",
|
||||
}
|
||||
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString(fmt.Sprintf("%-32s %-32s\n", "Collector Name", "[PerfID] Perflib Object"))
|
||||
|
||||
for _, cname := range ConfigDefaults.CollectorsEnabled {
|
||||
sb.WriteString(fmt.Sprintf("%-32s %-32s\n", cname, collectorDesc[cname]))
|
||||
}
|
||||
|
||||
app.UsageTemplate(sb.String()).Usage(nil)
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
c.config.CollectorsEnabled = strings.Split(collectorsEnabled, ",")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
collectorFuncs := map[string]func() error{
|
||||
adAccessProcesses: c.buildADAccessProcesses,
|
||||
transportQueues: c.buildTransportQueues,
|
||||
httpProxy: c.buildHTTPProxy,
|
||||
activeSync: c.buildActiveSync,
|
||||
availabilityService: c.buildAvailabilityService,
|
||||
outlookWebAccess: c.buildOWA,
|
||||
autoDiscover: c.buildAutoDiscover,
|
||||
workloadManagement: c.buildWorkloadManagementWorkloads,
|
||||
rpcClientAccess: c.buildRPC,
|
||||
mapiHttpEmsmdb: c.buildMapiHttpEmsmdb,
|
||||
}
|
||||
|
||||
for _, collectorName := range c.config.CollectorsEnabled {
|
||||
if err := collectorFuncs[collectorName](); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// desc creates a new prometheus description
|
||||
desc := func(metricName string, description string, labels ...string) *prometheus.Desc {
|
||||
return prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, metricName),
|
||||
description,
|
||||
labels,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
c.rpcAveragedLatency = desc("rpc_avg_latency_sec", "The latency (sec) averaged for the past 1024 packets")
|
||||
c.rpcRequests = desc("rpc_requests", "Number of client requests currently being processed by the RPC Client Access service")
|
||||
c.activeUserCount = desc("rpc_active_user_count", "Number of unique users that have shown some kind of activity in the last 2 minutes")
|
||||
c.connectionCount = desc("rpc_connection_count", "Total number of client connections maintained")
|
||||
c.rpcOperationsPerSec = desc("rpc_operations_total", "The rate at which RPC operations occur")
|
||||
c.userCount = desc("rpc_user_count", "Number of users")
|
||||
c.ldapReadTime = desc("ldap_read_time_sec", "Time (sec) to send an LDAP read request and receive a response", "name")
|
||||
c.ldapSearchTime = desc("ldap_search_time_sec", "Time (sec) to send an LDAP search request and receive a response", "name")
|
||||
c.ldapWriteTime = desc("ldap_write_time_sec", "Time (sec) to send an LDAP Add/Modify/Delete request and receive a response", "name")
|
||||
c.ldapTimeoutErrorsPerSec = desc("ldap_timeout_errors_total", "Total number of LDAP timeout errors", "name")
|
||||
c.longRunningLDAPOperationsPerMin = desc("ldap_long_running_ops_per_sec", "Long Running LDAP operations per second", "name")
|
||||
c.externalActiveRemoteDeliveryQueueLength = desc("transport_queues_external_active_remote_delivery", "External Active Remote Delivery Queue length", "name")
|
||||
c.internalActiveRemoteDeliveryQueueLength = desc("transport_queues_internal_active_remote_delivery", "Internal Active Remote Delivery Queue length", "name")
|
||||
c.activeMailboxDeliveryQueueLength = desc("transport_queues_active_mailbox_delivery", "Active Mailbox Delivery Queue length", "name")
|
||||
c.retryMailboxDeliveryQueueLength = desc("transport_queues_retry_mailbox_delivery", "Retry Mailbox Delivery Queue length", "name")
|
||||
c.unreachableQueueLength = desc("transport_queues_unreachable", "Unreachable Queue length", "name")
|
||||
c.externalLargestDeliveryQueueLength = desc("transport_queues_external_largest_delivery", "External Largest Delivery Queue length", "name")
|
||||
c.internalLargestDeliveryQueueLength = desc("transport_queues_internal_largest_delivery", "Internal Largest Delivery Queue length", "name")
|
||||
c.poisonQueueLength = desc("transport_queues_poison", "Poison Queue length", "name")
|
||||
c.mailboxServerLocatorAverageLatency = desc("http_proxy_mailbox_server_locator_avg_latency_sec", "Average latency (sec) of MailboxServerLocator web service calls", "name")
|
||||
c.averageAuthenticationLatency = desc("http_proxy_avg_auth_latency", "Average time spent authenticating CAS requests over the last 200 samples", "name")
|
||||
c.outstandingProxyRequests = desc("http_proxy_outstanding_proxy_requests", "Number of concurrent outstanding proxy requests", "name")
|
||||
c.proxyRequestsPerSec = desc("http_proxy_requests_total", "Number of proxy requests processed each second", "name")
|
||||
c.availabilityRequestsSec = desc("avail_service_requests_per_sec", "Number of requests serviced per second")
|
||||
c.currentUniqueUsers = desc("owa_current_unique_users", "Number of unique users currently logged on to Outlook Web App")
|
||||
c.owaRequestsPerSec = desc("owa_requests_total", "Number of requests handled by Outlook Web App per second")
|
||||
c.autoDiscoverRequestsPerSec = desc("autodiscover_requests_total", "Number of autodiscover service requests processed each second")
|
||||
c.activeTasks = desc("workload_active_tasks", "Number of active tasks currently running in the background for workload management", "name")
|
||||
c.completedTasks = desc("workload_completed_tasks", "Number of workload management tasks that have been completed", "name")
|
||||
c.queuedTasks = desc("workload_queued_tasks", "Number of workload management tasks that are currently queued up waiting to be processed", "name")
|
||||
c.yieldedTasks = desc("workload_yielded_tasks", "The total number of tasks that have been yielded by a workload", "name")
|
||||
c.isActive = desc("workload_is_active", "Active indicates whether the workload is in an active (1) or paused (0) state", "name")
|
||||
c.activeSyncRequestsPerSec = desc("activesync_requests_total", "Num HTTP requests received from the client via ASP.NET per sec. Shows Current user load")
|
||||
c.averageCASProcessingLatency = desc("http_proxy_avg_cas_processing_latency_sec", "Average latency (sec) of CAS processing time over the last 200 reqs", "name")
|
||||
c.mailboxServerProxyFailureRate = desc("http_proxy_mailbox_proxy_failure_rate", "% of failures between this CAS and MBX servers over the last 200 samples", "name")
|
||||
c.pingCommandsPending = desc("activesync_ping_cmds_pending", "Number of ping commands currently pending in the queue")
|
||||
c.syncCommandsPerSec = desc("activesync_sync_cmds_total", "Number of sync commands processed per second. Clients use this command to synchronize items within a folder")
|
||||
c.activeUserCountMapiHttpEmsMDB = desc("mapihttp_emsmdb_active_user_count", "Number of unique outlook users that have shown some kind of activity in the last 2 minutes")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect collects exchange metrics and sends them to prometheus.
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
collectorFuncs := map[string]func(ch chan<- prometheus.Metric) error{
|
||||
adAccessProcesses: c.collectADAccessProcesses,
|
||||
transportQueues: c.collectTransportQueues,
|
||||
httpProxy: c.collectHTTPProxy,
|
||||
activeSync: c.collectActiveSync,
|
||||
availabilityService: c.collectAvailabilityService,
|
||||
outlookWebAccess: c.collectOWA,
|
||||
autoDiscover: c.collectAutoDiscover,
|
||||
workloadManagement: c.collectWorkloadManagementWorkloads,
|
||||
rpcClientAccess: c.collectRPC,
|
||||
mapiHttpEmsmdb: c.collectMapiHttpEmsmdb,
|
||||
}
|
||||
|
||||
errs := make([]error, len(c.config.CollectorsEnabled))
|
||||
|
||||
for i, collectorName := range c.config.CollectorsEnabled {
|
||||
errs[i] = collectorFuncs[collectorName](ch)
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// toLabelName converts strings to lowercase and replaces all whitespaces and dots with underscores.
|
||||
func (c *Collector) toLabelName(name string) string {
|
||||
s := strings.ReplaceAll(strings.Join(strings.Fields(strings.ToLower(name)), "_"), ".", "_")
|
||||
s = strings.ReplaceAll(s, "__", "_")
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// msToSec converts from ms to seconds.
|
||||
func (c *Collector) msToSec(t float64) float64 {
|
||||
return t / 1000
|
||||
}
|
||||
65
internal/collector/exchange/exchange_active_sync.go
Normal file
65
internal/collector/exchange/exchange_active_sync.go
Normal file
@@ -0,0 +1,65 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
requestsPerSec = "Requests/sec"
|
||||
pingCommandsPending = "Ping Commands Pending"
|
||||
syncCommandsPerSec = "Sync Commands/sec"
|
||||
)
|
||||
|
||||
func (c *Collector) buildActiveSync() error {
|
||||
counters := []string{
|
||||
requestsPerSec,
|
||||
pingCommandsPending,
|
||||
syncCommandsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorActiveSync, err = perfdata.NewCollector("MSExchange ActiveSync", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange ActiveSync collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectActiveSync(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorActiveSync.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange ActiveSync metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange ActiveSync returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeSyncRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.pingCommandsPending,
|
||||
prometheus.GaugeValue,
|
||||
data[pingCommandsPending].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.syncCommandsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[syncCommandsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
95
internal/collector/exchange/exchange_ad_access_processes.go
Normal file
95
internal/collector/exchange/exchange_ad_access_processes.go
Normal file
@@ -0,0 +1,95 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
ldapReadTime = "LDAP Read Time"
|
||||
ldapSearchTime = "LDAP Search Time"
|
||||
ldapWriteTime = "LDAP Write Time"
|
||||
ldapTimeoutErrorsPerSec = "LDAP Timeout Errors/sec"
|
||||
longRunningLDAPOperationsPerMin = "Long Running LDAP Operations/min"
|
||||
)
|
||||
|
||||
func (c *Collector) buildADAccessProcesses() error {
|
||||
counters := []string{
|
||||
ldapReadTime,
|
||||
ldapSearchTime,
|
||||
ldapWriteTime,
|
||||
ldapTimeoutErrorsPerSec,
|
||||
longRunningLDAPOperationsPerMin,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorADAccessProcesses, err = perfdata.NewCollector("MSExchange ADAccess Processes", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange ADAccess Processes collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectADAccessProcesses(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorADAccessProcesses.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange ADAccess Processes metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange ADAccess Processes returned empty result set")
|
||||
}
|
||||
|
||||
labelUseCount := make(map[string]int)
|
||||
|
||||
for name, data := range perfData {
|
||||
labelName := c.toLabelName(name)
|
||||
|
||||
// Since we're not including the PID suffix from the instance names in the label names, we get an occasional duplicate.
|
||||
// This seems to affect about 4 instances only of this object.
|
||||
labelUseCount[labelName]++
|
||||
if labelUseCount[labelName] > 1 {
|
||||
labelName = fmt.Sprintf("%s_%d", labelName, labelUseCount[labelName])
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapReadTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(data[ldapReadTime].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapSearchTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(data[ldapSearchTime].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapWriteTime,
|
||||
prometheus.CounterValue,
|
||||
c.msToSec(data[ldapWriteTime].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ldapTimeoutErrorsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[ldapTimeoutErrorsPerSec].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.longRunningLDAPOperationsPerMin,
|
||||
prometheus.CounterValue,
|
||||
data[longRunningLDAPOperationsPerMin].FirstValue*60,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
47
internal/collector/exchange/exchange_autodiscover.go
Normal file
47
internal/collector/exchange/exchange_autodiscover.go
Normal file
@@ -0,0 +1,47 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func (c *Collector) buildAutoDiscover() error {
|
||||
counters := []string{
|
||||
requestsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorAutoDiscover, err = perfdata.NewCollector("MSExchange Autodiscover", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange Autodiscover collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectAutoDiscover(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorAutoDiscover.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange Autodiscover metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange Autodiscover returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.autoDiscoverRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
45
internal/collector/exchange/exchange_availability_service.go
Normal file
45
internal/collector/exchange/exchange_availability_service.go
Normal file
@@ -0,0 +1,45 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func (c *Collector) buildAvailabilityService() error {
|
||||
counters := []string{}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorAvailabilityService, err = perfdata.NewCollector("MSExchange Availability Service", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange Availability Service collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectAvailabilityService(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorAvailabilityService.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange Availability Service metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange Availability Service returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.availabilityRequestsSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
93
internal/collector/exchange/exchange_http_proxy.go
Normal file
93
internal/collector/exchange/exchange_http_proxy.go
Normal file
@@ -0,0 +1,93 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
mailboxServerLocatorAverageLatency = "MailboxServerLocator Average Latency (Moving Average)"
|
||||
averageAuthenticationLatency = "Average Authentication Latency"
|
||||
averageCASProcessingLatency = "Average ClientAccess Server Processing Latency"
|
||||
mailboxServerProxyFailureRate = "Mailbox Server Proxy Failure Rate"
|
||||
outstandingProxyRequests = "Outstanding Proxy Requests"
|
||||
proxyRequestsPerSec = "Proxy Requests/Sec"
|
||||
)
|
||||
|
||||
func (c *Collector) buildHTTPProxy() error {
|
||||
counters := []string{
|
||||
mailboxServerLocatorAverageLatency,
|
||||
averageAuthenticationLatency,
|
||||
averageCASProcessingLatency,
|
||||
mailboxServerProxyFailureRate,
|
||||
outstandingProxyRequests,
|
||||
proxyRequestsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorHttpProxy, err = perfdata.NewCollector("MSExchange HttpProxy", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange HttpProxy collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectHTTPProxy(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorHttpProxy.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange HttpProxy Service metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange HttpProxy Service returned empty result set")
|
||||
}
|
||||
|
||||
for name, data := range perfData {
|
||||
labelName := c.toLabelName(name)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mailboxServerLocatorAverageLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(data[mailboxServerLocatorAverageLatency].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.averageAuthenticationLatency,
|
||||
prometheus.GaugeValue,
|
||||
data[averageAuthenticationLatency].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.averageCASProcessingLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(data[averageCASProcessingLatency].FirstValue),
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.mailboxServerProxyFailureRate,
|
||||
prometheus.GaugeValue,
|
||||
data[mailboxServerProxyFailureRate].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outstandingProxyRequests,
|
||||
prometheus.GaugeValue,
|
||||
data[outstandingProxyRequests].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.proxyRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[proxyRequestsPerSec].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
51
internal/collector/exchange/exchange_mapi_http_emsmdb.go
Normal file
51
internal/collector/exchange/exchange_mapi_http_emsmdb.go
Normal file
@@ -0,0 +1,51 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
activeUserCount = "Active User Count"
|
||||
)
|
||||
|
||||
func (c *Collector) buildMapiHttpEmsmdb() error {
|
||||
counters := []string{
|
||||
activeUserCount,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorMapiHttpEmsmdb, err = perfdata.NewCollector("MSExchange MapiHttp Emsmdb", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange MapiHttp Emsmdb: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectMapiHttpEmsmdb(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorMapiHttpEmsmdb.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange MapiHttp Emsmdb metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange MapiHttp Emsmdb returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeUserCountMapiHttpEmsMDB,
|
||||
prometheus.GaugeValue,
|
||||
data[activeUserCount].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
58
internal/collector/exchange/exchange_outlook_web_access.go
Normal file
58
internal/collector/exchange/exchange_outlook_web_access.go
Normal file
@@ -0,0 +1,58 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
currentUniqueUsers = "Current Unique Users"
|
||||
// requestsPerSec = "Requests/sec"
|
||||
)
|
||||
|
||||
func (c *Collector) buildOWA() error {
|
||||
counters := []string{
|
||||
currentUniqueUsers,
|
||||
requestsPerSec,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorOWA, err = perfdata.NewCollector("MSExchange OWA", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange OWA collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectOWA(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorOWA.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange OWA metrics: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange OWA returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentUniqueUsers,
|
||||
prometheus.GaugeValue,
|
||||
data[currentUniqueUsers].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.owaRequestsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[requestsPerSec].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
86
internal/collector/exchange/exchange_rpc_client_access.go
Normal file
86
internal/collector/exchange/exchange_rpc_client_access.go
Normal file
@@ -0,0 +1,86 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
rpcAveragedLatency = "RPC Averaged Latency"
|
||||
rpcRequests = "RPC Requests"
|
||||
// activeUserCount = "Active User Count"
|
||||
connectionCount = "Connection Count"
|
||||
rpcOperationsPerSec = "RPC Operations/sec"
|
||||
userCount = "User Count"
|
||||
)
|
||||
|
||||
func (c *Collector) buildRPC() error {
|
||||
counters := []string{
|
||||
rpcAveragedLatency,
|
||||
rpcRequests,
|
||||
activeUserCount,
|
||||
connectionCount,
|
||||
rpcOperationsPerSec,
|
||||
userCount,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorRpcClientAccess, err = perfdata.NewCollector("MSExchange RpcClientAccess", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange RpcClientAccess collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectRPC(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorRpcClientAccess.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange RpcClientAccess: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange RpcClientAccess returned empty result set")
|
||||
}
|
||||
|
||||
for _, data := range perfData {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcAveragedLatency,
|
||||
prometheus.GaugeValue,
|
||||
c.msToSec(data[rpcAveragedLatency].FirstValue),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcRequests,
|
||||
prometheus.GaugeValue,
|
||||
data[rpcRequests].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeUserCount,
|
||||
prometheus.GaugeValue,
|
||||
data[activeUserCount].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.connectionCount,
|
||||
prometheus.GaugeValue,
|
||||
data[connectionCount].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.rpcOperationsPerSec,
|
||||
prometheus.CounterValue,
|
||||
data[rpcOperationsPerSec].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.userCount,
|
||||
prometheus.GaugeValue,
|
||||
data[userCount].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
14
internal/collector/exchange/exchange_test.go
Normal file
14
internal/collector/exchange/exchange_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/exchange"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, exchange.Name, exchange.NewWithFlags)
|
||||
}
|
||||
110
internal/collector/exchange/exchange_transport_queues.go
Normal file
110
internal/collector/exchange/exchange_transport_queues.go
Normal file
@@ -0,0 +1,110 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
externalActiveRemoteDeliveryQueueLength = "External Active Remote Delivery Queue Length"
|
||||
internalActiveRemoteDeliveryQueueLength = "Internal Active Remote Delivery Queue Length"
|
||||
activeMailboxDeliveryQueueLength = "Active Mailbox Delivery Queue Length"
|
||||
retryMailboxDeliveryQueueLength = "Retry Mailbox Delivery Queue Length"
|
||||
unreachableQueueLength = "Unreachable Queue Length"
|
||||
externalLargestDeliveryQueueLength = "External Largest Delivery Queue Length"
|
||||
internalLargestDeliveryQueueLength = "Internal Largest Delivery Queue Length"
|
||||
poisonQueueLength = "Poison Queue Length"
|
||||
)
|
||||
|
||||
func (c *Collector) buildTransportQueues() error {
|
||||
counters := []string{
|
||||
externalActiveRemoteDeliveryQueueLength,
|
||||
internalActiveRemoteDeliveryQueueLength,
|
||||
activeMailboxDeliveryQueueLength,
|
||||
retryMailboxDeliveryQueueLength,
|
||||
unreachableQueueLength,
|
||||
externalLargestDeliveryQueueLength,
|
||||
internalLargestDeliveryQueueLength,
|
||||
poisonQueueLength,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorTransportQueues, err = perfdata.NewCollector("MSExchangeTransport Queues", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchangeTransport Queues collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectTransportQueues(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorTransportQueues.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchangeTransport Queues: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchangeTransport Queues returned empty result set")
|
||||
}
|
||||
|
||||
for name, data := range perfData {
|
||||
labelName := c.toLabelName(name)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalActiveRemoteDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[externalActiveRemoteDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.internalActiveRemoteDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[internalActiveRemoteDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeMailboxDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[activeMailboxDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.retryMailboxDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[retryMailboxDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.unreachableQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[unreachableQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.externalLargestDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[externalLargestDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.internalLargestDeliveryQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[internalLargestDeliveryQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.poisonQueueLength,
|
||||
prometheus.GaugeValue,
|
||||
data[poisonQueueLength].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
86
internal/collector/exchange/exchange_workload_management.go
Normal file
86
internal/collector/exchange/exchange_workload_management.go
Normal file
@@ -0,0 +1,86 @@
|
||||
//go:build windows
|
||||
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
activeTasks = "ActiveTasks"
|
||||
completedTasks = "CompletedTasks"
|
||||
queuedTasks = "QueuedTasks"
|
||||
yieldedTasks = "YieldedTasks"
|
||||
isActive = "Active"
|
||||
)
|
||||
|
||||
func (c *Collector) buildWorkloadManagementWorkloads() error {
|
||||
counters := []string{
|
||||
activeTasks,
|
||||
completedTasks,
|
||||
queuedTasks,
|
||||
yieldedTasks,
|
||||
isActive,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorWorkloadManagementWorkloads, err = perfdata.NewCollector("MSExchange WorkloadManagement Workloads", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create MSExchange WorkloadManagement Workloads collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectWorkloadManagementWorkloads(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorWorkloadManagementWorkloads.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect MSExchange WorkloadManagement Workloads: %w", err)
|
||||
}
|
||||
|
||||
if len(perfData) == 0 {
|
||||
return errors.New("perflib query for MSExchange WorkloadManagement Workloads returned empty result set")
|
||||
}
|
||||
|
||||
for name, data := range perfData {
|
||||
labelName := c.toLabelName(name)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeTasks,
|
||||
prometheus.GaugeValue,
|
||||
data[activeTasks].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.completedTasks,
|
||||
prometheus.CounterValue,
|
||||
data[completedTasks].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.queuedTasks,
|
||||
prometheus.CounterValue,
|
||||
data[queuedTasks].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.yieldedTasks,
|
||||
prometheus.CounterValue,
|
||||
data[yieldedTasks].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.isActive,
|
||||
prometheus.GaugeValue,
|
||||
data[isActive].FirstValue,
|
||||
labelName,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
165
internal/collector/filetime/filetime.go
Normal file
165
internal/collector/filetime/filetime.go
Normal file
@@ -0,0 +1,165 @@
|
||||
//go:build windows
|
||||
|
||||
package filetime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/bmatcuk/doublestar/v4"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "filetime"
|
||||
|
||||
type Config struct {
|
||||
FilePatterns []string
|
||||
}
|
||||
|
||||
var ConfigDefaults = Config{
|
||||
FilePatterns: []string{},
|
||||
}
|
||||
|
||||
// A Collector is a Prometheus Collector for collecting file times.
|
||||
type Collector struct {
|
||||
config Config
|
||||
|
||||
logger *slog.Logger
|
||||
fileMTime *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
if config.FilePatterns == nil {
|
||||
config.FilePatterns = ConfigDefaults.FilePatterns
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
c.config.FilePatterns = make([]string, 0)
|
||||
|
||||
var filePatterns string
|
||||
|
||||
app.Flag(
|
||||
"collector.filetime.file-patterns",
|
||||
"Comma-separated list of file patterns. Each pattern is a glob pattern that can contain `*`, `?`, and `**` (recursive). See https://github.com/bmatcuk/doublestar#patterns",
|
||||
).Default(strings.Join(ConfigDefaults.FilePatterns, ",")).StringVar(&filePatterns)
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
// doublestar.Glob() requires forward slashes
|
||||
c.config.FilePatterns = strings.Split(filepath.ToSlash(filePatterns), ",")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
c.logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
c.logger.Info("filetime collector is in an experimental state! It may subject to change.")
|
||||
|
||||
c.fileMTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "mtime_timestamp_seconds"),
|
||||
"File modification time",
|
||||
[]string{"file"},
|
||||
nil,
|
||||
)
|
||||
|
||||
for _, filePattern := range c.config.FilePatterns {
|
||||
basePath, pattern := doublestar.SplitPattern(filePattern)
|
||||
|
||||
_, err := doublestar.Glob(os.DirFS(basePath), pattern, doublestar.WithFilesOnly())
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid glob pattern: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
for _, filePattern := range c.config.FilePatterns {
|
||||
wg.Add(1)
|
||||
|
||||
go func(filePattern string) {
|
||||
defer wg.Done()
|
||||
|
||||
if err := c.collectGlobFilePath(ch, filePattern); err != nil {
|
||||
c.logger.Error("failed collecting metrics for filepath",
|
||||
slog.String("filepath", filePattern),
|
||||
slog.Any("err", err),
|
||||
)
|
||||
}
|
||||
}(filePattern)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectGlobFilePath(ch chan<- prometheus.Metric, filePattern string) error {
|
||||
basePath, pattern := doublestar.SplitPattern(filePattern)
|
||||
basePathFS := os.DirFS(basePath)
|
||||
|
||||
matches, err := doublestar.Glob(basePathFS, pattern, doublestar.WithFilesOnly())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to glob: %w", err)
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
filePath := filepath.Join(basePath, match)
|
||||
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
c.logger.Warn("failed to state file",
|
||||
slog.String("file", filePath),
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fileMTime,
|
||||
prometheus.GaugeValue,
|
||||
float64(fileInfo.ModTime().UTC().Unix()),
|
||||
filePath,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
20
internal/collector/filetime/filetime_test.go
Normal file
20
internal/collector/filetime/filetime_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
//go:build windows
|
||||
|
||||
package filetime_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/filetime"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, filetime.Name, filetime.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
testutils.TestCollector(t, filetime.New, &filetime.Config{
|
||||
FilePatterns: []string{"*.*"},
|
||||
})
|
||||
}
|
||||
@@ -4,13 +4,14 @@ package fsrmquota
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/utils"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "fsrmquota"
|
||||
@@ -21,7 +22,8 @@ var ConfigDefaults = Config{}
|
||||
|
||||
type Collector struct {
|
||||
config Config
|
||||
wmiClient *wmi.Client
|
||||
miSession *mi.Session
|
||||
miQuery mi.Query
|
||||
|
||||
quotasCount *prometheus.Desc
|
||||
peakUsage *prometheus.Desc
|
||||
@@ -55,20 +57,22 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
if wmiClient == nil || wmiClient.SWbemServicesClient == nil {
|
||||
return errors.New("wmiClient or SWbemServicesClient is nil")
|
||||
func (c *Collector) Build(_ *slog.Logger, miSession *mi.Session) error {
|
||||
if miSession == nil {
|
||||
return errors.New("miSession is nil")
|
||||
}
|
||||
|
||||
c.wmiClient = wmiClient
|
||||
miQuery, err := mi.NewQuery("SELECT * FROM MSFT_FSRMQuota")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
c.miQuery = miQuery
|
||||
c.miSession = miSession
|
||||
|
||||
c.quotasCount = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "count"),
|
||||
@@ -128,47 +132,33 @@ func (c *Collector) Build(_ *slog.Logger, wmiClient *wmi.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
logger.Error("failed collecting fsrmquota metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MSFT_FSRMQuota docs:
|
||||
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/fsrm/msft-fsrmquota
|
||||
type MSFT_FSRMQuota struct {
|
||||
Name string
|
||||
Name string `mi:"Name"`
|
||||
|
||||
Path string
|
||||
PeakUsage uint64
|
||||
Size uint64
|
||||
Usage uint64
|
||||
Description string
|
||||
Template string
|
||||
// Threshold string
|
||||
Disabled bool
|
||||
MatchesTemplate bool
|
||||
SoftLimit bool
|
||||
Path string `mi:"Path"`
|
||||
PeakUsage uint64 `mi:"PeakUsage"`
|
||||
Size uint64 `mi:"Size"`
|
||||
Usage uint64 `mi:"Usage"`
|
||||
Description string `mi:"Description"`
|
||||
Template string `mi:"Template"`
|
||||
// Threshold string `mi:"Threshold"`
|
||||
Disabled bool `mi:"Disabled"`
|
||||
MatchesTemplate bool `mi:"MatchesTemplate"`
|
||||
SoftLimit bool `mi:"SoftLimit"`
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
var dst []MSFT_FSRMQuota
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootWindowsFSRM, c.miQuery); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
var count int
|
||||
|
||||
if err := c.wmiClient.Query("SELECT * FROM MSFT_FSRMQuota", &dst, nil, "root/microsoft/windows/fsrm"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, quota := range dst {
|
||||
count++
|
||||
path := quota.Path
|
||||
14
internal/collector/fsrmquota/fsrmquota_test.go
Normal file
14
internal/collector/fsrmquota/fsrmquota_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package fsrmquota_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/fsrmquota"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, fsrmquota.Name, fsrmquota.NewWithFlags)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
14
internal/collector/hyperv/hyperv_test.go
Normal file
14
internal/collector/hyperv/hyperv_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package hyperv_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/hyperv"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, hyperv.Name, hyperv.NewWithFlags)
|
||||
}
|
||||
279
internal/collector/iis/iis.go
Normal file
279
internal/collector/iis/iis.go
Normal file
@@ -0,0 +1,279 @@
|
||||
//go:build windows
|
||||
|
||||
package iis
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
const Name = "iis"
|
||||
|
||||
type Config struct {
|
||||
SiteInclude *regexp.Regexp `yaml:"site_include"`
|
||||
SiteExclude *regexp.Regexp `yaml:"site_exclude"`
|
||||
AppInclude *regexp.Regexp `yaml:"app_include"`
|
||||
AppExclude *regexp.Regexp `yaml:"app_exclude"`
|
||||
}
|
||||
|
||||
var ConfigDefaults = Config{
|
||||
SiteInclude: types.RegExpAny,
|
||||
SiteExclude: types.RegExpEmpty,
|
||||
AppInclude: types.RegExpAny,
|
||||
AppExclude: types.RegExpEmpty,
|
||||
}
|
||||
|
||||
type Collector struct {
|
||||
config Config
|
||||
iisVersion simpleVersion
|
||||
|
||||
info *prometheus.Desc
|
||||
collectorWebService
|
||||
collectorAppPoolWAS
|
||||
collectorW3SVCW3WP
|
||||
collectorWebServiceCache
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
if config == nil {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
if config.AppExclude == nil {
|
||||
config.AppExclude = ConfigDefaults.AppExclude
|
||||
}
|
||||
|
||||
if config.AppInclude == nil {
|
||||
config.AppInclude = ConfigDefaults.AppInclude
|
||||
}
|
||||
|
||||
if config.SiteExclude == nil {
|
||||
config.SiteExclude = ConfigDefaults.SiteExclude
|
||||
}
|
||||
|
||||
if config.SiteInclude == nil {
|
||||
config.SiteInclude = ConfigDefaults.SiteInclude
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
|
||||
var appExclude, appInclude, siteExclude, siteInclude string
|
||||
|
||||
app.Flag(
|
||||
"collector.iis.app-exclude",
|
||||
"Regexp of apps to exclude. App name must both match include and not match exclude to be included.",
|
||||
).Default("").StringVar(&appExclude)
|
||||
|
||||
app.Flag(
|
||||
"collector.iis.app-include",
|
||||
"Regexp of apps to include. App name must both match include and not match exclude to be included.",
|
||||
).Default(".+").StringVar(&appInclude)
|
||||
|
||||
app.Flag(
|
||||
"collector.iis.site-exclude",
|
||||
"Regexp of sites to exclude. Site name must both match include and not match exclude to be included.",
|
||||
).Default("").StringVar(&siteExclude)
|
||||
|
||||
app.Flag(
|
||||
"collector.iis.site-include",
|
||||
"Regexp of sites to include. Site name must both match include and not match exclude to be included.",
|
||||
).Default(".+").StringVar(&siteInclude)
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
var err error
|
||||
|
||||
c.config.AppExclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", appExclude))
|
||||
if err != nil {
|
||||
return fmt.Errorf("collector.iis.app-exclude: %w", err)
|
||||
}
|
||||
|
||||
c.config.AppInclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", appInclude))
|
||||
if err != nil {
|
||||
return fmt.Errorf("collector.iis.app-include: %w", err)
|
||||
}
|
||||
|
||||
c.config.SiteExclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", siteExclude))
|
||||
if err != nil {
|
||||
return fmt.Errorf("collector.iis.site-exclude: %w", err)
|
||||
}
|
||||
|
||||
c.config.SiteInclude, err = regexp.Compile(fmt.Sprintf("^(?:%s)$", siteInclude))
|
||||
if err != nil {
|
||||
return fmt.Errorf("collector.iis.site-include: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollectorWebService.Close()
|
||||
c.perfDataCollectorAppPoolWAS.Close()
|
||||
c.perfDataCollectorW3SVCW3WP.Close()
|
||||
c.perfDataCollectorWebServiceCache.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
|
||||
c.iisVersion = c.getIISVersion(logger)
|
||||
|
||||
c.info = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||
"ISS information",
|
||||
[]string{},
|
||||
prometheus.Labels{"version": fmt.Sprintf("%d.%d", c.iisVersion.major, c.iisVersion.minor)},
|
||||
)
|
||||
|
||||
if err := c.buildWebService(); err != nil {
|
||||
return fmt.Errorf("failed to build Web Service collector: %w", err)
|
||||
}
|
||||
|
||||
if err := c.buildAppPoolWAS(); err != nil {
|
||||
return fmt.Errorf("failed to build APP_POOL_WAS collector: %w", err)
|
||||
}
|
||||
|
||||
if err := c.buildW3SVCW3WP(); err != nil {
|
||||
return fmt.Errorf("failed to build W3SVC_W3WP collector: %w", err)
|
||||
}
|
||||
|
||||
if err := c.buildWebServiceCache(); err != nil {
|
||||
return fmt.Errorf("failed to build Web Service Cache collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type simpleVersion struct {
|
||||
major uint64
|
||||
minor uint64
|
||||
}
|
||||
|
||||
func (c *Collector) getIISVersion(logger *slog.Logger) simpleVersion {
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\InetStp\`, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
logger.Warn("Couldn't open registry to determine IIS version",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return simpleVersion{}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err = k.Close()
|
||||
if err != nil {
|
||||
logger.Warn("Failed to close registry key",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
major, _, err := k.GetIntegerValue("MajorVersion")
|
||||
if err != nil {
|
||||
logger.Warn("Couldn't open registry to determine IIS version",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return simpleVersion{}
|
||||
}
|
||||
|
||||
minor, _, err := k.GetIntegerValue("MinorVersion")
|
||||
if err != nil {
|
||||
logger.Warn("Couldn't open registry to determine IIS version",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return simpleVersion{}
|
||||
}
|
||||
|
||||
logger.Debug(fmt.Sprintf("Detected IIS %d.%d\n", major, minor))
|
||||
|
||||
return simpleVersion{
|
||||
major: major,
|
||||
minor: minor,
|
||||
}
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.info,
|
||||
prometheus.GaugeValue,
|
||||
1,
|
||||
)
|
||||
|
||||
errs := make([]error, 0, 4)
|
||||
|
||||
if err := c.collectWebService(ch); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect Web Service metrics: %w", err))
|
||||
}
|
||||
|
||||
if err := c.collectAppPoolWAS(ch); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect APP_POOL_WAS metrics: %w", err))
|
||||
}
|
||||
|
||||
if err := c.collectW3SVCW3WP(ch); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect W3SVC_W3WP metrics: %w", err))
|
||||
}
|
||||
|
||||
if err := c.collectWebServiceCache(ch); err != nil {
|
||||
errs = append(errs, fmt.Errorf("failed to collect Web Service Cache metrics: %w", err))
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// deduplicateIISNames deduplicate IIS site names from various IIS perflib objects.
|
||||
//
|
||||
// E.G. Given the following list of site names, "Site_B" would be
|
||||
// discarded, and "Site_B#2" would be kept and presented as "Site_B" in the
|
||||
// Collector metrics.
|
||||
// [ "Site_A", "Site_B", "Site_C", "Site_B#2" ].
|
||||
func deduplicateIISNames(counterValues map[string]map[string]perfdata.CounterValues) {
|
||||
services := slices.Collect(maps.Keys(counterValues))
|
||||
|
||||
// Ensure IIS entry with the highest suffix occurs last
|
||||
slices.Sort(services)
|
||||
|
||||
// Use map to deduplicate IIS entries
|
||||
for _, entry := range services {
|
||||
name := strings.Split(entry, "#")[0]
|
||||
if name == entry {
|
||||
continue
|
||||
}
|
||||
|
||||
counterValues[name] = counterValues[entry]
|
||||
delete(counterValues, entry)
|
||||
}
|
||||
}
|
||||
265
internal/collector/iis/iis_app_pool_was.go
Normal file
265
internal/collector/iis/iis_app_pool_was.go
Normal file
@@ -0,0 +1,265 @@
|
||||
//go:build windows
|
||||
|
||||
package iis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type collectorAppPoolWAS struct {
|
||||
perfDataCollectorAppPoolWAS *perfdata.Collector
|
||||
|
||||
currentApplicationPoolState *prometheus.Desc
|
||||
currentApplicationPoolUptime *prometheus.Desc
|
||||
currentWorkerProcesses *prometheus.Desc
|
||||
maximumWorkerProcesses *prometheus.Desc
|
||||
recentWorkerProcessFailures *prometheus.Desc
|
||||
timeSinceLastWorkerProcessFailure *prometheus.Desc
|
||||
totalApplicationPoolRecycles *prometheus.Desc
|
||||
totalApplicationPoolUptime *prometheus.Desc
|
||||
totalWorkerProcessesCreated *prometheus.Desc
|
||||
totalWorkerProcessFailures *prometheus.Desc
|
||||
totalWorkerProcessPingFailures *prometheus.Desc
|
||||
totalWorkerProcessShutdownFailures *prometheus.Desc
|
||||
totalWorkerProcessStartupFailures *prometheus.Desc
|
||||
}
|
||||
|
||||
const (
|
||||
CurrentApplicationPoolState = "Current Application Pool State"
|
||||
CurrentApplicationPoolUptime = "Current Application Pool Uptime"
|
||||
CurrentWorkerProcesses = "Current Worker Processes"
|
||||
MaximumWorkerProcesses = "Maximum Worker Processes"
|
||||
RecentWorkerProcessFailures = "Recent Worker Process Failures"
|
||||
TimeSinceLastWorkerProcessFailure = "Time Since Last Worker Process Failure"
|
||||
TotalApplicationPoolRecycles = "Total Application Pool Recycles"
|
||||
TotalApplicationPoolUptime = "Total Application Pool Uptime"
|
||||
TotalWorkerProcessesCreated = "Total Worker Processes Created"
|
||||
TotalWorkerProcessFailures = "Total Worker Process Failures"
|
||||
TotalWorkerProcessPingFailures = "Total Worker Process Ping Failures"
|
||||
TotalWorkerProcessShutdownFailures = "Total Worker Process Shutdown Failures"
|
||||
TotalWorkerProcessStartupFailures = "Total Worker Process Startup Failures"
|
||||
)
|
||||
|
||||
var applicationStates = map[uint32]string{
|
||||
1: "Uninitialized",
|
||||
2: "Initialized",
|
||||
3: "Running",
|
||||
4: "Disabling",
|
||||
5: "Disabled",
|
||||
6: "Shutdown Pending",
|
||||
7: "Delete Pending",
|
||||
}
|
||||
|
||||
func (c *Collector) buildAppPoolWAS() error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorAppPoolWAS, err = perfdata.NewCollector("APP_POOL_WAS", perfdata.InstanceAll, []string{
|
||||
CurrentApplicationPoolState,
|
||||
CurrentApplicationPoolUptime,
|
||||
CurrentWorkerProcesses,
|
||||
MaximumWorkerProcesses,
|
||||
RecentWorkerProcessFailures,
|
||||
TimeSinceLastWorkerProcessFailure,
|
||||
TotalApplicationPoolRecycles,
|
||||
TotalApplicationPoolUptime,
|
||||
TotalWorkerProcessesCreated,
|
||||
TotalWorkerProcessFailures,
|
||||
TotalWorkerProcessPingFailures,
|
||||
TotalWorkerProcessShutdownFailures,
|
||||
TotalWorkerProcessStartupFailures,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create APP_POOL_WAS collector: %w", err)
|
||||
}
|
||||
|
||||
// APP_POOL_WAS
|
||||
c.currentApplicationPoolState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_application_pool_state"),
|
||||
"The current status of the application pool (1 - Uninitialized, 2 - Initialized, 3 - Running, 4 - Disabling, 5 - Disabled, 6 - Shutdown Pending, 7 - Delete Pending) (CurrentApplicationPoolState)",
|
||||
[]string{"app", "state"},
|
||||
nil,
|
||||
)
|
||||
c.currentApplicationPoolUptime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_application_pool_start_time"),
|
||||
"The unix timestamp for the application pool start time (CurrentApplicationPoolUptime)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.currentWorkerProcesses = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_worker_processes"),
|
||||
"The current number of worker processes that are running in the application pool (CurrentWorkerProcesses)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.maximumWorkerProcesses = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "maximum_worker_processes"),
|
||||
"The maximum number of worker processes that have been created for the application pool since Windows Process Activation Service (WAS) started (MaximumWorkerProcesses)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.recentWorkerProcessFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "recent_worker_process_failures"),
|
||||
"The number of times that worker processes for the application pool failed during the rapid-fail protection interval (RecentWorkerProcessFailures)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.timeSinceLastWorkerProcessFailure = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "time_since_last_worker_process_failure"),
|
||||
"The length of time, in seconds, since the last worker process failure occurred for the application pool (TimeSinceLastWorkerProcessFailure)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.totalApplicationPoolRecycles = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "total_application_pool_recycles"),
|
||||
"The number of times that the application pool has been recycled since Windows Process Activation Service (WAS) started (TotalApplicationPoolRecycles)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.totalApplicationPoolUptime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "total_application_pool_start_time"),
|
||||
"The unix timestamp for the application pool of when the Windows Process Activation Service (WAS) started (TotalApplicationPoolUptime)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.totalWorkerProcessesCreated = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "total_worker_processes_created"),
|
||||
"The number of worker processes created for the application pool since Windows Process Activation Service (WAS) started (TotalWorkerProcessesCreated)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.totalWorkerProcessFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "total_worker_process_failures"),
|
||||
"The number of times that worker processes have crashed since the application pool was started (TotalWorkerProcessFailures)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.totalWorkerProcessPingFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "total_worker_process_ping_failures"),
|
||||
"The number of times that Windows Process Activation Service (WAS) did not receive a response to ping messages sent to a worker process (TotalWorkerProcessPingFailures)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.totalWorkerProcessShutdownFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "total_worker_process_shutdown_failures"),
|
||||
"The number of times that Windows Process Activation Service (WAS) failed to shut down a worker process (TotalWorkerProcessShutdownFailures)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
c.totalWorkerProcessStartupFailures = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "total_worker_process_startup_failures"),
|
||||
"The number of times that Windows Process Activation Service (WAS) failed to start a worker process (TotalWorkerProcessStartupFailures)",
|
||||
[]string{"app"},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectAppPoolWAS(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorWebService.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect APP_POOL_WAS metrics: %w", err)
|
||||
}
|
||||
|
||||
deduplicateIISNames(perfData)
|
||||
|
||||
for name, app := range perfData {
|
||||
if c.config.AppExclude.MatchString(name) || !c.config.AppInclude.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
for key, label := range applicationStates {
|
||||
isCurrentState := 0.0
|
||||
if key == uint32(app[CurrentApplicationPoolState].FirstValue) {
|
||||
isCurrentState = 1.0
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentApplicationPoolState,
|
||||
prometheus.GaugeValue,
|
||||
isCurrentState,
|
||||
name,
|
||||
label,
|
||||
)
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentApplicationPoolUptime,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentApplicationPoolUptime].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentWorkerProcesses,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentWorkerProcesses].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.maximumWorkerProcesses,
|
||||
prometheus.GaugeValue,
|
||||
app[MaximumWorkerProcesses].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recentWorkerProcessFailures,
|
||||
prometheus.GaugeValue,
|
||||
app[RecentWorkerProcessFailures].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.timeSinceLastWorkerProcessFailure,
|
||||
prometheus.GaugeValue,
|
||||
app[TimeSinceLastWorkerProcessFailure].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalApplicationPoolRecycles,
|
||||
prometheus.CounterValue,
|
||||
app[TotalApplicationPoolRecycles].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalApplicationPoolUptime,
|
||||
prometheus.CounterValue,
|
||||
app[TotalApplicationPoolUptime].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalWorkerProcessesCreated,
|
||||
prometheus.CounterValue,
|
||||
app[TotalWorkerProcessesCreated].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalWorkerProcessFailures,
|
||||
prometheus.CounterValue,
|
||||
app[TotalWorkerProcessFailures].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalWorkerProcessPingFailures,
|
||||
prometheus.CounterValue,
|
||||
app[TotalWorkerProcessPingFailures].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalWorkerProcessShutdownFailures,
|
||||
prometheus.CounterValue,
|
||||
app[TotalWorkerProcessShutdownFailures].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalWorkerProcessStartupFailures,
|
||||
prometheus.CounterValue,
|
||||
app[TotalWorkerProcessStartupFailures].FirstValue,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
14
internal/collector/iis/iis_bench_test.go
Normal file
14
internal/collector/iis/iis_bench_test.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build windows
|
||||
|
||||
package iis_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/iis"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, iis.Name, iis.NewWithFlags)
|
||||
}
|
||||
745
internal/collector/iis/iis_w3svc_w3wp.go
Normal file
745
internal/collector/iis/iis_w3svc_w3wp.go
Normal file
@@ -0,0 +1,745 @@
|
||||
//go:build windows
|
||||
|
||||
package iis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type collectorW3SVCW3WP struct {
|
||||
perfDataCollectorW3SVCW3WP *perfdata.Collector
|
||||
|
||||
// W3SVC_W3WP
|
||||
threads *prometheus.Desc
|
||||
maximumThreads *prometheus.Desc
|
||||
|
||||
requestsTotal *prometheus.Desc
|
||||
requestsActive *prometheus.Desc
|
||||
|
||||
activeFlushedEntries *prometheus.Desc
|
||||
|
||||
currentFileCacheMemoryUsage *prometheus.Desc
|
||||
maximumFileCacheMemoryUsage *prometheus.Desc
|
||||
fileCacheFlushesTotal *prometheus.Desc
|
||||
fileCacheQueriesTotal *prometheus.Desc
|
||||
fileCacheHitsTotal *prometheus.Desc
|
||||
filesCached *prometheus.Desc
|
||||
filesCachedTotal *prometheus.Desc
|
||||
filesFlushedTotal *prometheus.Desc
|
||||
|
||||
uriCacheFlushesTotal *prometheus.Desc
|
||||
uriCacheQueriesTotal *prometheus.Desc
|
||||
uriCacheHitsTotal *prometheus.Desc
|
||||
urisCached *prometheus.Desc
|
||||
urisCachedTotal *prometheus.Desc
|
||||
urisFlushedTotal *prometheus.Desc
|
||||
|
||||
metadataCached *prometheus.Desc
|
||||
metadataCacheFlushes *prometheus.Desc
|
||||
metadataCacheQueriesTotal *prometheus.Desc
|
||||
metadataCacheHitsTotal *prometheus.Desc
|
||||
metadataCachedTotal *prometheus.Desc
|
||||
metadataFlushedTotal *prometheus.Desc
|
||||
|
||||
outputCacheActiveFlushedItems *prometheus.Desc
|
||||
outputCacheItems *prometheus.Desc
|
||||
outputCacheMemoryUsage *prometheus.Desc
|
||||
outputCacheQueriesTotal *prometheus.Desc
|
||||
outputCacheHitsTotal *prometheus.Desc
|
||||
outputCacheFlushedItemsTotal *prometheus.Desc
|
||||
outputCacheFlushesTotal *prometheus.Desc
|
||||
|
||||
// IIS 8+ Only
|
||||
requestErrorsTotal *prometheus.Desc
|
||||
webSocketRequestsActive *prometheus.Desc
|
||||
webSocketConnectionAttempts *prometheus.Desc
|
||||
webSocketConnectionsAccepted *prometheus.Desc
|
||||
webSocketConnectionsRejected *prometheus.Desc
|
||||
}
|
||||
|
||||
var workerProcessNameExtractor = regexp.MustCompile(`^(\d+)_(.+)$`)
|
||||
|
||||
const (
|
||||
Threads = "Active Threads Count"
|
||||
MaximumThreads = "Maximum Threads Count"
|
||||
|
||||
RequestsTotal = "Total HTTP Requests Served"
|
||||
RequestsActive = "Active Requests"
|
||||
|
||||
ActiveFlushedEntries = "Active Flushed Entries"
|
||||
|
||||
CurrentFileCacheMemoryUsage = "Current File Cache Memory Usage"
|
||||
MaximumFileCacheMemoryUsage = "Maximum File Cache Memory Usage"
|
||||
FileCacheFlushesTotal = "File Cache Flushes"
|
||||
FileCacheHitsTotal = "File Cache Hits"
|
||||
FileCacheMissesTotal = "File Cache Misses"
|
||||
FilesCached = "Current Files Cached"
|
||||
FilesCachedTotal = "Total Files Cached"
|
||||
FilesFlushedTotal = "Total Flushed Files"
|
||||
|
||||
URICacheFlushesTotal = "Total Flushed URIs"
|
||||
URICacheFlushesTotalKernel = "Total Flushed URIs"
|
||||
URIsFlushedTotalKernel = "Kernel: Total Flushed URIs"
|
||||
URICacheHitsTotal = "URI Cache Hits"
|
||||
URICacheHitsTotalKernel = "Kernel: URI Cache Hits"
|
||||
URICacheMissesTotal = "URI Cache Misses"
|
||||
URICacheMissesTotalKernel = "Kernel: URI Cache Misses"
|
||||
URIsCached = "Current URIs Cached"
|
||||
URIsCachedKernel = "Kernel: Current URIs Cached"
|
||||
URIsCachedTotal = "Total URIs Cached"
|
||||
URIsCachedTotalKernel = "Total URIs Cached"
|
||||
URIsFlushedTotal = "Total Flushed URIs"
|
||||
|
||||
MetaDataCacheHits = "Metadata Cache Hits"
|
||||
MetaDataCacheMisses = "Metadata Cache Misses"
|
||||
MetadataCached = "Current Metadata Cached"
|
||||
MetadataCacheFlushes = "Metadata Cache Flushes"
|
||||
MetadataCachedTotal = "Total Metadata Cached"
|
||||
MetadataFlushedTotal = "Total Flushed Metadata"
|
||||
|
||||
OutputCacheActiveFlushedItems = "Output Cache Current Flushed Items"
|
||||
OutputCacheItems = "Output Cache Current Items"
|
||||
OutputCacheMemoryUsage = "Output Cache Current Memory Usage"
|
||||
OutputCacheHitsTotal = "Output Cache Total Hits"
|
||||
OutputCacheMissesTotal = "Output Cache Total Misses"
|
||||
OutputCacheFlushedItemsTotal = "Output Cache Total Flushed Items"
|
||||
OutputCacheFlushesTotal = "Output Cache Total Flushes"
|
||||
|
||||
// IIS8
|
||||
RequestErrors500 = "% 500 HTTP Response Sent"
|
||||
RequestErrors503 = "% 503 HTTP Response Sent"
|
||||
RequestErrors404 = "% 404 HTTP Response Sent"
|
||||
RequestErrors403 = "% 403 HTTP Response Sent"
|
||||
RequestErrors401 = "% 401 HTTP Response Sent"
|
||||
|
||||
WebSocketRequestsActive = "WebSocket Active Requests"
|
||||
WebSocketConnectionAttempts = "WebSocket Connection Attempts / Sec"
|
||||
WebSocketConnectionsAccepted = "WebSocket Connections Accepted / Sec"
|
||||
WebSocketConnectionsRejected = "WebSocket Connections Rejected / Sec"
|
||||
)
|
||||
|
||||
func (c *Collector) buildW3SVCW3WP() error {
|
||||
counters := []string{
|
||||
Threads,
|
||||
MaximumThreads,
|
||||
RequestsTotal,
|
||||
RequestsActive,
|
||||
ActiveFlushedEntries,
|
||||
CurrentFileCacheMemoryUsage,
|
||||
MaximumFileCacheMemoryUsage,
|
||||
FileCacheFlushesTotal,
|
||||
FileCacheHitsTotal,
|
||||
FileCacheMissesTotal,
|
||||
FilesCached,
|
||||
FilesCachedTotal,
|
||||
FilesFlushedTotal,
|
||||
URICacheFlushesTotal,
|
||||
URICacheFlushesTotalKernel,
|
||||
URIsFlushedTotalKernel,
|
||||
URICacheHitsTotal,
|
||||
URICacheHitsTotalKernel,
|
||||
URICacheMissesTotal,
|
||||
URICacheMissesTotalKernel,
|
||||
URIsCached,
|
||||
URIsCachedKernel,
|
||||
URIsCachedTotal,
|
||||
URIsCachedTotalKernel,
|
||||
URIsFlushedTotal,
|
||||
MetaDataCacheHits,
|
||||
MetaDataCacheMisses,
|
||||
MetadataCached,
|
||||
MetadataCacheFlushes,
|
||||
MetadataCachedTotal,
|
||||
MetadataFlushedTotal,
|
||||
OutputCacheActiveFlushedItems,
|
||||
OutputCacheItems,
|
||||
OutputCacheMemoryUsage,
|
||||
OutputCacheHitsTotal,
|
||||
OutputCacheMissesTotal,
|
||||
OutputCacheFlushedItemsTotal,
|
||||
OutputCacheFlushesTotal,
|
||||
}
|
||||
|
||||
if c.iisVersion.major >= 8 {
|
||||
counters = append(counters, []string{
|
||||
RequestErrors500,
|
||||
RequestErrors503,
|
||||
RequestErrors404,
|
||||
RequestErrors403,
|
||||
RequestErrors401,
|
||||
WebSocketRequestsActive,
|
||||
WebSocketConnectionAttempts,
|
||||
WebSocketConnectionsAccepted,
|
||||
WebSocketConnectionsRejected,
|
||||
}...)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorW3SVCW3WP, err = perfdata.NewCollector("W3SVC_W3WP", perfdata.InstanceAll, counters)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create W3SVC_W3WP collector: %w", err)
|
||||
}
|
||||
|
||||
// W3SVC_W3WP
|
||||
c.threads = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_threads"),
|
||||
"Number of threads actively processing requests in the worker process",
|
||||
[]string{"app", "pid", "state"},
|
||||
nil,
|
||||
)
|
||||
c.maximumThreads = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_max_threads"),
|
||||
"Maximum number of threads to which the thread pool can grow as needed",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.requestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_requests_total"),
|
||||
"Total number of HTTP requests served by the worker process",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.requestsActive = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_current_requests"),
|
||||
"Current number of requests being processed by the worker process",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.activeFlushedEntries = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_cache_active_flushed_entries"),
|
||||
"Number of file handles cached in user-mode that will be closed when all current transfers complete.",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.currentFileCacheMemoryUsage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_memory_bytes"),
|
||||
"Current number of bytes used by user-mode file cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.maximumFileCacheMemoryUsage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_max_memory_bytes"),
|
||||
"Maximum number of bytes used by user-mode file cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.fileCacheFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_flushes_total"),
|
||||
"Total number of files removed from the user-mode cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.fileCacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_queries_total"),
|
||||
"Total file cache queries (hits + misses)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.fileCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_hits_total"),
|
||||
"Total number of successful lookups in the user-mode file cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.filesCached = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_items"),
|
||||
"Current number of files whose contents are present in user-mode cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.filesCachedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_items_total"),
|
||||
"Total number of files whose contents were ever added to the user-mode cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.filesFlushedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_file_cache_items_flushed_total"),
|
||||
"Total number of file handles that have been removed from the user-mode cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.uriCacheFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_uri_cache_flushes_total"),
|
||||
"Total number of URI cache flushes (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.uriCacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_uri_cache_queries_total"),
|
||||
"Total number of uri cache queries (hits + misses)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.uriCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_uri_cache_hits_total"),
|
||||
"Total number of successful lookups in the user-mode URI cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.urisCached = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_uri_cache_items"),
|
||||
"Number of URI information blocks currently in the user-mode cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.urisCachedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_uri_cache_items_total"),
|
||||
"Total number of URI information blocks added to the user-mode cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.urisFlushedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_uri_cache_items_flushed_total"),
|
||||
"The number of URI information blocks that have been removed from the user-mode cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.metadataCached = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_metadata_cache_items"),
|
||||
"Number of metadata information blocks currently present in user-mode cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.metadataCacheFlushes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_metadata_cache_flushes_total"),
|
||||
"Total number of user-mode metadata cache flushes (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.metadataCacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_metadata_cache_queries_total"),
|
||||
"Total metadata cache queries (hits + misses)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.metadataCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_metadata_cache_hits_total"),
|
||||
"Total number of successful lookups in the user-mode metadata cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.metadataCachedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_metadata_cache_items_cached_total"),
|
||||
"Total number of metadata information blocks added to the user-mode cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.metadataFlushedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_metadata_cache_items_flushed_total"),
|
||||
"Total number of metadata information blocks removed from the user-mode cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.outputCacheActiveFlushedItems = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_output_cache_active_flushed_items"),
|
||||
"",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.outputCacheItems = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_output_cache_items"),
|
||||
"Number of items current present in output cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.outputCacheMemoryUsage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_output_cache_memory_bytes"),
|
||||
"Current number of bytes used by output cache",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.outputCacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_output_queries_total"),
|
||||
"Total number of output cache queries (hits + misses)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.outputCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_output_cache_hits_total"),
|
||||
"Total number of successful lookups in output cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.outputCacheFlushedItemsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_output_cache_items_flushed_total"),
|
||||
"Total number of items flushed from output cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.outputCacheFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_output_cache_flushes_total"),
|
||||
"Total number of flushes of output cache (since service startup)",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
// W3SVC_W3WP_IIS8
|
||||
c.requestErrorsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_request_errors_total"),
|
||||
"Total number of requests that returned an error",
|
||||
[]string{"app", "pid", "status_code"},
|
||||
nil,
|
||||
)
|
||||
c.webSocketRequestsActive = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_current_websocket_requests"),
|
||||
"",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.webSocketConnectionAttempts = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_websocket_connection_attempts_total"),
|
||||
"",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.webSocketConnectionsAccepted = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_websocket_connection_accepted_total"),
|
||||
"",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
c.webSocketConnectionsRejected = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "worker_websocket_connection_rejected_total"),
|
||||
"",
|
||||
[]string{"app", "pid"},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectW3SVCW3WP(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorW3SVCW3WP.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect APP_POOL_WAS metrics: %w", err)
|
||||
}
|
||||
|
||||
deduplicateIISNames(perfData)
|
||||
|
||||
for name, app := range perfData {
|
||||
if c.config.AppExclude.MatchString(name) || !c.config.AppInclude.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract the apppool name from the format <PID>_<NAME>
|
||||
pid := workerProcessNameExtractor.ReplaceAllString(name, "$1")
|
||||
|
||||
name := workerProcessNameExtractor.ReplaceAllString(name, "$2")
|
||||
if name == "" || name == "_Total" ||
|
||||
c.config.AppExclude.MatchString(name) ||
|
||||
!c.config.AppInclude.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Duplicate instances are suffixed # with an index number. These should be ignored
|
||||
if strings.Contains(name, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.threads,
|
||||
prometheus.GaugeValue,
|
||||
app[Threads].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
"busy",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.maximumThreads,
|
||||
prometheus.CounterValue,
|
||||
app[MaximumThreads].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[RequestsTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestsActive,
|
||||
prometheus.CounterValue,
|
||||
app[RequestsActive].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.activeFlushedEntries,
|
||||
prometheus.GaugeValue,
|
||||
app[ActiveFlushedEntries].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentFileCacheMemoryUsage,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentFileCacheMemoryUsage].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.maximumFileCacheMemoryUsage,
|
||||
prometheus.CounterValue,
|
||||
app[MaximumFileCacheMemoryUsage].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fileCacheFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[FileCacheFlushesTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fileCacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[FileCacheHitsTotal].FirstValue+app[FileCacheMissesTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.fileCacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[FileCacheHitsTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.filesCached,
|
||||
prometheus.GaugeValue,
|
||||
app[FilesCached].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.filesCachedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[FilesCachedTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.filesFlushedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[FilesFlushedTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.uriCacheFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[URICacheFlushesTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.uriCacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[URICacheHitsTotal].FirstValue+app[URICacheMissesTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.uriCacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[URICacheHitsTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.urisCached,
|
||||
prometheus.GaugeValue,
|
||||
app[URIsCached].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.urisCachedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[URIsCachedTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.urisFlushedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[URIsFlushedTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.metadataCached,
|
||||
prometheus.GaugeValue,
|
||||
app[MetadataCached].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.metadataCacheFlushes,
|
||||
prometheus.CounterValue,
|
||||
app[MetadataCacheFlushes].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.metadataCacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[MetaDataCacheHits].FirstValue+app[MetaDataCacheMisses].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.metadataCacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[MetaDataCacheHits].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.metadataCachedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[MetadataCachedTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.metadataFlushedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[MetadataFlushedTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outputCacheActiveFlushedItems,
|
||||
prometheus.CounterValue,
|
||||
app[OutputCacheActiveFlushedItems].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outputCacheItems,
|
||||
prometheus.CounterValue,
|
||||
app[OutputCacheItems].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outputCacheMemoryUsage,
|
||||
prometheus.CounterValue,
|
||||
app[OutputCacheMemoryUsage].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outputCacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[OutputCacheHitsTotal].FirstValue+app[OutputCacheMissesTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outputCacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[OutputCacheHitsTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outputCacheFlushedItemsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[OutputCacheFlushedItemsTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.outputCacheFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[OutputCacheFlushesTotal].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
|
||||
if c.iisVersion.major >= 8 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestErrorsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[RequestErrors401].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
"401",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestErrorsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[RequestErrors403].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
"403",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestErrorsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[RequestErrors404].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
"404",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestErrorsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[RequestErrors500].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
"500",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.requestErrorsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[RequestErrors503].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
"503",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.webSocketRequestsActive,
|
||||
prometheus.CounterValue,
|
||||
app[WebSocketRequestsActive].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.webSocketConnectionAttempts,
|
||||
prometheus.CounterValue,
|
||||
app[WebSocketConnectionAttempts].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.webSocketConnectionsAccepted,
|
||||
prometheus.CounterValue,
|
||||
app[WebSocketConnectionsAccepted].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.webSocketConnectionsRejected,
|
||||
prometheus.CounterValue,
|
||||
app[WebSocketConnectionsRejected].FirstValue,
|
||||
name,
|
||||
pid,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
516
internal/collector/iis/iis_web_service.go
Normal file
516
internal/collector/iis/iis_web_service.go
Normal file
@@ -0,0 +1,516 @@
|
||||
//go:build windows
|
||||
|
||||
package iis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type collectorWebService struct {
|
||||
perfDataCollectorWebService *perfdata.Collector
|
||||
|
||||
currentAnonymousUsers *prometheus.Desc
|
||||
currentBlockedAsyncIORequests *prometheus.Desc
|
||||
currentCGIRequests *prometheus.Desc
|
||||
currentConnections *prometheus.Desc
|
||||
currentISAPIExtensionRequests *prometheus.Desc
|
||||
currentNonAnonymousUsers *prometheus.Desc
|
||||
serviceUptime *prometheus.Desc
|
||||
totalBytesReceived *prometheus.Desc
|
||||
totalBytesSent *prometheus.Desc
|
||||
totalAnonymousUsers *prometheus.Desc
|
||||
totalBlockedAsyncIORequests *prometheus.Desc
|
||||
totalCGIRequests *prometheus.Desc
|
||||
totalConnectionAttemptsAllInstances *prometheus.Desc
|
||||
totalRequests *prometheus.Desc
|
||||
totalFilesReceived *prometheus.Desc
|
||||
totalFilesSent *prometheus.Desc
|
||||
totalISAPIExtensionRequests *prometheus.Desc
|
||||
totalLockedErrors *prometheus.Desc
|
||||
totalLogonAttempts *prometheus.Desc
|
||||
totalNonAnonymousUsers *prometheus.Desc
|
||||
totalNotFoundErrors *prometheus.Desc
|
||||
totalRejectedAsyncIORequests *prometheus.Desc
|
||||
}
|
||||
|
||||
const (
|
||||
CurrentAnonymousUsers = "Current Anonymous Users"
|
||||
CurrentBlockedAsyncIORequests = "Current Blocked Async I/O Requests"
|
||||
CurrentCGIRequests = "Current CGI Requests"
|
||||
CurrentConnections = "Current Connections"
|
||||
CurrentISAPIExtensionRequests = "Current ISAPI Extension Requests"
|
||||
CurrentNonAnonymousUsers = "Current NonAnonymous Users"
|
||||
ServiceUptime = "Service Uptime"
|
||||
TotalBytesReceived = "Total Bytes Received"
|
||||
TotalBytesSent = "Total Bytes Sent"
|
||||
TotalAnonymousUsers = "Total Anonymous Users"
|
||||
TotalBlockedAsyncIORequests = "Total Blocked Async I/O Requests"
|
||||
TotalCGIRequests = "Total CGI Requests"
|
||||
TotalConnectionAttemptsAllInstances = "Total Connection Attempts (all instances)"
|
||||
TotalFilesReceived = "Total Files Received"
|
||||
TotalFilesSent = "Total Files Sent"
|
||||
TotalISAPIExtensionRequests = "Total ISAPI Extension Requests"
|
||||
TotalLockedErrors = "Total Locked Errors"
|
||||
TotalLogonAttempts = "Total Logon Attempts"
|
||||
TotalNonAnonymousUsers = "Total NonAnonymous Users"
|
||||
TotalNotFoundErrors = "Total Not Found Errors"
|
||||
TotalRejectedAsyncIORequests = "Total Rejected Async I/O Requests"
|
||||
TotalCopyRequests = "Total Copy Requests"
|
||||
TotalDeleteRequests = "Total Delete Requests"
|
||||
TotalGetRequests = "Total Get Requests"
|
||||
TotalHeadRequests = "Total Head Requests"
|
||||
TotalLockRequests = "Total Lock Requests"
|
||||
TotalMkcolRequests = "Total Mkcol Requests"
|
||||
TotalMoveRequests = "Total Move Requests"
|
||||
TotalOptionsRequests = "Total Options Requests"
|
||||
TotalOtherRequests = "Total Other Request Methods"
|
||||
TotalPostRequests = "Total Post Requests"
|
||||
TotalPropfindRequests = "Total Propfind Requests"
|
||||
TotalProppatchRequests = "Total Proppatch Requests"
|
||||
TotalPutRequests = "Total Put Requests"
|
||||
TotalSearchRequests = "Total Search Requests"
|
||||
TotalTraceRequests = "Total Trace Requests"
|
||||
TotalUnlockRequests = "Total Unlock Requests"
|
||||
)
|
||||
|
||||
func (c *Collector) buildWebService() error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorWebService, err = perfdata.NewCollector("Web Service", perfdata.InstanceAll, []string{
|
||||
CurrentAnonymousUsers,
|
||||
CurrentBlockedAsyncIORequests,
|
||||
CurrentCGIRequests,
|
||||
CurrentConnections,
|
||||
CurrentISAPIExtensionRequests,
|
||||
CurrentNonAnonymousUsers,
|
||||
ServiceUptime,
|
||||
TotalBytesReceived,
|
||||
TotalBytesSent,
|
||||
TotalAnonymousUsers,
|
||||
TotalBlockedAsyncIORequests,
|
||||
TotalCGIRequests,
|
||||
TotalConnectionAttemptsAllInstances,
|
||||
TotalFilesReceived,
|
||||
TotalFilesSent,
|
||||
TotalISAPIExtensionRequests,
|
||||
TotalLockedErrors,
|
||||
TotalLogonAttempts,
|
||||
TotalNonAnonymousUsers,
|
||||
TotalNotFoundErrors,
|
||||
TotalRejectedAsyncIORequests,
|
||||
TotalCopyRequests,
|
||||
TotalDeleteRequests,
|
||||
TotalGetRequests,
|
||||
TotalHeadRequests,
|
||||
TotalLockRequests,
|
||||
TotalMkcolRequests,
|
||||
TotalMoveRequests,
|
||||
TotalOptionsRequests,
|
||||
TotalOtherRequests,
|
||||
TotalPostRequests,
|
||||
TotalPropfindRequests,
|
||||
TotalProppatchRequests,
|
||||
TotalPutRequests,
|
||||
TotalSearchRequests,
|
||||
TotalTraceRequests,
|
||||
TotalUnlockRequests,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Web Service collector: %w", err)
|
||||
}
|
||||
|
||||
c.currentAnonymousUsers = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_anonymous_users"),
|
||||
"Number of users who currently have an anonymous connection using the Web service (WebService.CurrentAnonymousUsers)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.currentBlockedAsyncIORequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_blocked_async_io_requests"),
|
||||
"Current requests temporarily blocked due to bandwidth throttling settings (WebService.CurrentBlockedAsyncIORequests)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.currentCGIRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_cgi_requests"),
|
||||
"Current number of CGI requests being simultaneously processed by the Web service (WebService.CurrentCGIRequests)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.currentConnections = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_connections"),
|
||||
"Current number of connections established with the Web service (WebService.CurrentConnections)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.currentISAPIExtensionRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_isapi_extension_requests"),
|
||||
"Current number of ISAPI requests being simultaneously processed by the Web service (WebService.CurrentISAPIExtensionRequests)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.currentNonAnonymousUsers = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "current_non_anonymous_users"),
|
||||
"Number of users who currently have a non-anonymous connection using the Web service (WebService.CurrentNonAnonymousUsers)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.serviceUptime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "service_uptime"),
|
||||
"Number of seconds the WebService is up (WebService.ServiceUptime)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalBytesReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "received_bytes_total"),
|
||||
"Number of data bytes that have been received by the Web service (WebService.TotalBytesReceived)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalBytesSent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "sent_bytes_total"),
|
||||
"Number of data bytes that have been sent by the Web service (WebService.TotalBytesSent)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalAnonymousUsers = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "anonymous_users_total"),
|
||||
"Total number of users who established an anonymous connection with the Web service (WebService.TotalAnonymousUsers)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalBlockedAsyncIORequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "blocked_async_io_requests_total"),
|
||||
"Total requests temporarily blocked due to bandwidth throttling settings (WebService.TotalBlockedAsyncIORequests)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalCGIRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "cgi_requests_total"),
|
||||
"Total CGI requests is the total number of CGI requests (WebService.TotalCGIRequests)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalConnectionAttemptsAllInstances = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "connection_attempts_all_instances_total"),
|
||||
"Number of connections that have been attempted using the Web service (WebService.TotalConnectionAttemptsAllInstances)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
|
||||
"Number of HTTP requests (WebService.TotalRequests)",
|
||||
[]string{"site", "method"},
|
||||
nil,
|
||||
)
|
||||
c.totalFilesReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "files_received_total"),
|
||||
"Number of files received by the Web service (WebService.TotalFilesReceived)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalFilesSent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "files_sent_total"),
|
||||
"Number of files sent by the Web service (WebService.TotalFilesSent)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalISAPIExtensionRequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "ipapi_extension_requests_total"),
|
||||
"ISAPI Extension Requests received (WebService.TotalISAPIExtensionRequests)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalLockedErrors = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "locked_errors_total"),
|
||||
"Number of requests that couldn't be satisfied by the server because the requested resource was locked (WebService.TotalLockedErrors)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalLogonAttempts = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "logon_attempts_total"),
|
||||
"Number of logons attempts to the Web Service (WebService.TotalLogonAttempts)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalNonAnonymousUsers = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "non_anonymous_users_total"),
|
||||
"Number of users who established a non-anonymous connection with the Web service (WebService.TotalNonAnonymousUsers)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalNotFoundErrors = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "not_found_errors_total"),
|
||||
"Number of requests that couldn't be satisfied by the server because the requested document could not be found (WebService.TotalNotFoundErrors)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
c.totalRejectedAsyncIORequests = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "rejected_async_io_requests_total"),
|
||||
"Requests rejected due to bandwidth throttling settings (WebService.TotalRejectedAsyncIORequests)",
|
||||
[]string{"site"},
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectWebService(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorWebService.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect Web Service metrics: %w", err)
|
||||
}
|
||||
|
||||
deduplicateIISNames(perfData)
|
||||
|
||||
for name, app := range perfData {
|
||||
if c.config.SiteExclude.MatchString(name) || !c.config.SiteInclude.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentAnonymousUsers,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentAnonymousUsers].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentBlockedAsyncIORequests,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentBlockedAsyncIORequests].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentCGIRequests,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentCGIRequests].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentConnections,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentConnections].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentISAPIExtensionRequests,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentISAPIExtensionRequests].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.currentNonAnonymousUsers,
|
||||
prometheus.GaugeValue,
|
||||
app[CurrentNonAnonymousUsers].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceUptime,
|
||||
prometheus.GaugeValue,
|
||||
app[ServiceUptime].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalBytesReceived,
|
||||
prometheus.CounterValue,
|
||||
app[TotalBytesReceived].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalBytesSent,
|
||||
prometheus.CounterValue,
|
||||
app[TotalBytesSent].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalAnonymousUsers,
|
||||
prometheus.CounterValue,
|
||||
app[TotalAnonymousUsers].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalBlockedAsyncIORequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalBlockedAsyncIORequests].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalCGIRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalCGIRequests].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalConnectionAttemptsAllInstances,
|
||||
prometheus.CounterValue,
|
||||
app[TotalConnectionAttemptsAllInstances].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalFilesReceived,
|
||||
prometheus.CounterValue,
|
||||
app[TotalFilesReceived].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalFilesSent,
|
||||
prometheus.CounterValue,
|
||||
app[TotalFilesSent].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalISAPIExtensionRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalISAPIExtensionRequests].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalLockedErrors,
|
||||
prometheus.CounterValue,
|
||||
app[TotalLockedErrors].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalLogonAttempts,
|
||||
prometheus.CounterValue,
|
||||
app[TotalLogonAttempts].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalNonAnonymousUsers,
|
||||
prometheus.CounterValue,
|
||||
app[TotalNonAnonymousUsers].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalNotFoundErrors,
|
||||
prometheus.CounterValue,
|
||||
app[TotalNotFoundErrors].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRejectedAsyncIORequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalRejectedAsyncIORequests].FirstValue,
|
||||
name,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalOtherRequests].FirstValue,
|
||||
name,
|
||||
"other",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalCopyRequests].FirstValue,
|
||||
name,
|
||||
"COPY",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalDeleteRequests].FirstValue,
|
||||
name,
|
||||
"DELETE",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalGetRequests].FirstValue,
|
||||
name,
|
||||
"GET",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalHeadRequests].FirstValue,
|
||||
name,
|
||||
"HEAD",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalLockRequests].FirstValue,
|
||||
name,
|
||||
"LOCK",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalMkcolRequests].FirstValue,
|
||||
name,
|
||||
"MKCOL",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalMoveRequests].FirstValue,
|
||||
name,
|
||||
"MOVE",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalOptionsRequests].FirstValue,
|
||||
name,
|
||||
"OPTIONS",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalPostRequests].FirstValue,
|
||||
name,
|
||||
"POST",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalPropfindRequests].FirstValue,
|
||||
name,
|
||||
"PROPFIND",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalProppatchRequests].FirstValue,
|
||||
name,
|
||||
"PROPPATCH",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalPutRequests].FirstValue,
|
||||
name,
|
||||
"PUT",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalSearchRequests].FirstValue,
|
||||
name,
|
||||
"SEARCH",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalTraceRequests].FirstValue,
|
||||
name,
|
||||
"TRACE",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.totalRequests,
|
||||
prometheus.CounterValue,
|
||||
app[TotalUnlockRequests].FirstValue,
|
||||
name,
|
||||
"UNLOCK",
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
501
internal/collector/iis/iis_web_service_cache.go
Normal file
501
internal/collector/iis/iis_web_service_cache.go
Normal file
@@ -0,0 +1,501 @@
|
||||
//go:build windows
|
||||
|
||||
package iis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type collectorWebServiceCache struct {
|
||||
perfDataCollectorWebServiceCache *perfdata.Collector
|
||||
|
||||
serviceCacheActiveFlushedEntries *prometheus.Desc
|
||||
|
||||
serviceCacheCurrentFileCacheMemoryUsage *prometheus.Desc
|
||||
serviceCacheMaximumFileCacheMemoryUsage *prometheus.Desc
|
||||
serviceCacheFileCacheFlushesTotal *prometheus.Desc
|
||||
serviceCacheFileCacheQueriesTotal *prometheus.Desc
|
||||
serviceCacheFileCacheHitsTotal *prometheus.Desc
|
||||
serviceCacheFilesCached *prometheus.Desc
|
||||
serviceCacheFilesCachedTotal *prometheus.Desc
|
||||
serviceCacheFilesFlushedTotal *prometheus.Desc
|
||||
|
||||
serviceCacheURICacheFlushesTotal *prometheus.Desc
|
||||
serviceCacheURICacheQueriesTotal *prometheus.Desc
|
||||
serviceCacheURICacheHitsTotal *prometheus.Desc
|
||||
serviceCacheURIsCached *prometheus.Desc
|
||||
serviceCacheURIsCachedTotal *prometheus.Desc
|
||||
serviceCacheURIsFlushedTotal *prometheus.Desc
|
||||
|
||||
serviceCacheMetadataCached *prometheus.Desc
|
||||
serviceCacheMetadataCacheFlushes *prometheus.Desc
|
||||
serviceCacheMetadataCacheQueriesTotal *prometheus.Desc
|
||||
serviceCacheMetadataCacheHitsTotal *prometheus.Desc
|
||||
serviceCacheMetadataCachedTotal *prometheus.Desc
|
||||
serviceCacheMetadataFlushedTotal *prometheus.Desc
|
||||
|
||||
serviceCacheOutputCacheActiveFlushedItems *prometheus.Desc
|
||||
serviceCacheOutputCacheItems *prometheus.Desc
|
||||
serviceCacheOutputCacheMemoryUsage *prometheus.Desc
|
||||
serviceCacheOutputCacheQueriesTotal *prometheus.Desc
|
||||
serviceCacheOutputCacheHitsTotal *prometheus.Desc
|
||||
serviceCacheOutputCacheFlushedItemsTotal *prometheus.Desc
|
||||
serviceCacheOutputCacheFlushesTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
const (
|
||||
ServiceCacheActiveFlushedEntries = "Active Flushed Entries"
|
||||
ServiceCacheCurrentFileCacheMemoryUsage = "Current File Cache Memory Usage"
|
||||
ServiceCacheMaximumFileCacheMemoryUsage = "Maximum File Cache Memory Usage"
|
||||
ServiceCacheFileCacheFlushesTotal = "File Cache Flushes"
|
||||
ServiceCacheFileCacheHitsTotal = "File Cache Hits"
|
||||
ServiceCacheFileCacheMissesTotal = "File Cache Misses"
|
||||
ServiceCacheFilesCached = "Current Files Cached"
|
||||
ServiceCacheFilesCachedTotal = "Total Files Cached"
|
||||
ServiceCacheFilesFlushedTotal = "Total Flushed Files"
|
||||
ServiceCacheURICacheFlushesTotal = "Total Flushed URIs"
|
||||
ServiceCacheURICacheFlushesTotalKernel = "Total Flushed URIs"
|
||||
ServiceCacheURIsFlushedTotalKernel = "Kernel: Total Flushed URIs"
|
||||
ServiceCacheURICacheHitsTotal = "URI Cache Hits"
|
||||
ServiceCacheURICacheHitsTotalKernel = "Kernel: URI Cache Hits"
|
||||
ServiceCacheURICacheMissesTotal = "URI Cache Misses"
|
||||
ServiceCacheURICacheMissesTotalKernel = "Kernel: URI Cache Misses"
|
||||
ServiceCacheURIsCached = "Current URIs Cached"
|
||||
ServiceCacheURIsCachedKernel = "Kernel: Current URIs Cached"
|
||||
ServiceCacheURIsCachedTotal = "Total URIs Cached"
|
||||
ServiceCacheURIsCachedTotalKernel = "Total URIs Cached"
|
||||
ServiceCacheURIsFlushedTotal = "Total Flushed URIs"
|
||||
ServiceCacheMetaDataCacheHits = "Metadata Cache Hits"
|
||||
ServiceCacheMetaDataCacheMisses = "Metadata Cache Misses"
|
||||
ServiceCacheMetadataCached = "Current Metadata Cached"
|
||||
ServiceCacheMetadataCacheFlushes = "Metadata Cache Flushes"
|
||||
ServiceCacheMetadataCachedTotal = "Total Metadata Cached"
|
||||
ServiceCacheMetadataFlushedTotal = "Total Flushed Metadata"
|
||||
ServiceCacheOutputCacheActiveFlushedItems = "Output Cache Current Flushed Items"
|
||||
ServiceCacheOutputCacheItems = "Output Cache Current Items"
|
||||
ServiceCacheOutputCacheMemoryUsage = "Output Cache Current Memory Usage"
|
||||
ServiceCacheOutputCacheHitsTotal = "Output Cache Total Hits"
|
||||
ServiceCacheOutputCacheMissesTotal = "Output Cache Total Misses"
|
||||
ServiceCacheOutputCacheFlushedItemsTotal = "Output Cache Total Flushed Items"
|
||||
ServiceCacheOutputCacheFlushesTotal = "Output Cache Total Flushes"
|
||||
)
|
||||
|
||||
func (c *Collector) buildWebServiceCache() error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollectorWebService, err = perfdata.NewCollector("Web Service Cache", perfdata.InstanceAll, []string{
|
||||
ServiceCacheActiveFlushedEntries,
|
||||
ServiceCacheCurrentFileCacheMemoryUsage,
|
||||
ServiceCacheMaximumFileCacheMemoryUsage,
|
||||
ServiceCacheFileCacheFlushesTotal,
|
||||
ServiceCacheFileCacheHitsTotal,
|
||||
ServiceCacheFileCacheMissesTotal,
|
||||
ServiceCacheFilesCached,
|
||||
ServiceCacheFilesCachedTotal,
|
||||
ServiceCacheFilesFlushedTotal,
|
||||
ServiceCacheURICacheFlushesTotal,
|
||||
ServiceCacheURICacheFlushesTotalKernel,
|
||||
ServiceCacheURIsFlushedTotalKernel,
|
||||
ServiceCacheURICacheHitsTotal,
|
||||
ServiceCacheURICacheHitsTotalKernel,
|
||||
ServiceCacheURICacheMissesTotal,
|
||||
ServiceCacheURICacheMissesTotalKernel,
|
||||
ServiceCacheURIsCached,
|
||||
ServiceCacheURIsCachedKernel,
|
||||
ServiceCacheURIsCachedTotal,
|
||||
ServiceCacheURIsCachedTotalKernel,
|
||||
ServiceCacheURIsFlushedTotal,
|
||||
ServiceCacheMetaDataCacheHits,
|
||||
ServiceCacheMetaDataCacheMisses,
|
||||
ServiceCacheMetadataCached,
|
||||
ServiceCacheMetadataCacheFlushes,
|
||||
ServiceCacheMetadataCachedTotal,
|
||||
ServiceCacheMetadataFlushedTotal,
|
||||
ServiceCacheOutputCacheActiveFlushedItems,
|
||||
ServiceCacheOutputCacheItems,
|
||||
ServiceCacheOutputCacheMemoryUsage,
|
||||
ServiceCacheOutputCacheHitsTotal,
|
||||
ServiceCacheOutputCacheMissesTotal,
|
||||
ServiceCacheOutputCacheFlushedItemsTotal,
|
||||
ServiceCacheOutputCacheFlushesTotal,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create Web Service Cache collector: %w", err)
|
||||
}
|
||||
|
||||
// Web Service Cache
|
||||
c.serviceCacheActiveFlushedEntries = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_cache_active_flushed_entries"),
|
||||
"Number of file handles cached that will be closed when all current transfers complete.",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheCurrentFileCacheMemoryUsage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_memory_bytes"),
|
||||
"Current number of bytes used by file cache",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheMaximumFileCacheMemoryUsage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_max_memory_bytes"),
|
||||
"Maximum number of bytes used by file cache",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheFileCacheFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_flushes_total"),
|
||||
"Total number of file cache flushes (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheFileCacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_queries_total"),
|
||||
"Total number of file cache queries (hits + misses)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheFileCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_hits_total"),
|
||||
"Total number of successful lookups in the user-mode file cache",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheFilesCached = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_items"),
|
||||
"Current number of files whose contents are present in cache",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheFilesCachedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_items_total"),
|
||||
"Total number of files whose contents were ever added to the cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheFilesFlushedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_file_cache_items_flushed_total"),
|
||||
"Total number of file handles that have been removed from the cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheURICacheFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_uri_cache_flushes_total"),
|
||||
"Total number of URI cache flushes (since service startup)",
|
||||
[]string{"mode"},
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheURICacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_uri_cache_queries_total"),
|
||||
"Total number of uri cache queries (hits + misses)",
|
||||
[]string{"mode"},
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheURICacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_uri_cache_hits_total"),
|
||||
"Total number of successful lookups in the URI cache (since service startup)",
|
||||
[]string{"mode"},
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheURIsCached = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_uri_cache_items"),
|
||||
"Number of URI information blocks currently in the cache",
|
||||
[]string{"mode"},
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheURIsCachedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_uri_cache_items_total"),
|
||||
"Total number of URI information blocks added to the cache (since service startup)",
|
||||
[]string{"mode"},
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheURIsFlushedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_uri_cache_items_flushed_total"),
|
||||
"The number of URI information blocks that have been removed from the cache (since service startup)",
|
||||
[]string{"mode"},
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheMetadataCached = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_metadata_cache_items"),
|
||||
"Number of metadata information blocks currently present in cache",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheMetadataCacheFlushes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_metadata_cache_flushes_total"),
|
||||
"Total number of metadata cache flushes (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheMetadataCacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_metadata_cache_queries_total"),
|
||||
"Total metadata cache queries (hits + misses)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheMetadataCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_metadata_cache_hits_total"),
|
||||
"Total number of successful lookups in the metadata cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheMetadataCachedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_metadata_cache_items_cached_total"),
|
||||
"Total number of metadata information blocks added to the cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheMetadataFlushedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_metadata_cache_items_flushed_total"),
|
||||
"Total number of metadata information blocks removed from the cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheOutputCacheActiveFlushedItems = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_output_cache_active_flushed_items"),
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheOutputCacheItems = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_output_cache_items"),
|
||||
"Number of items current present in output cache",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheOutputCacheMemoryUsage = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_output_cache_memory_bytes"),
|
||||
"Current number of bytes used by output cache",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheOutputCacheQueriesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_output_cache_queries_total"),
|
||||
"Total output cache queries (hits + misses)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheOutputCacheHitsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_output_cache_hits_total"),
|
||||
"Total number of successful lookups in output cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheOutputCacheFlushedItemsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_output_cache_items_flushed_total"),
|
||||
"Total number of items flushed from output cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.serviceCacheOutputCacheFlushesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "server_output_cache_flushes_total"),
|
||||
"Total number of flushes of output cache (since service startup)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectWebServiceCache(ch chan<- prometheus.Metric) error {
|
||||
perfData, err := c.perfDataCollectorWebService.Collect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect Web Service Cache metrics: %w", err)
|
||||
}
|
||||
|
||||
deduplicateIISNames(perfData)
|
||||
|
||||
for name, app := range perfData {
|
||||
if c.config.SiteExclude.MatchString(name) || !c.config.SiteInclude.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheActiveFlushedEntries,
|
||||
prometheus.GaugeValue,
|
||||
app[ServiceCacheActiveFlushedEntries].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheCurrentFileCacheMemoryUsage,
|
||||
prometheus.GaugeValue,
|
||||
app[ServiceCacheCurrentFileCacheMemoryUsage].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheMaximumFileCacheMemoryUsage,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheMaximumFileCacheMemoryUsage].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheFileCacheFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheFileCacheFlushesTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheFileCacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheFileCacheHitsTotal].FirstValue+app[ServiceCacheFileCacheMissesTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheFileCacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheFileCacheHitsTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheFilesCached,
|
||||
prometheus.GaugeValue,
|
||||
app[ServiceCacheFilesCached].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheFilesCachedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheFilesCachedTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheFilesFlushedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheFilesFlushedTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURICacheFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURICacheFlushesTotal].FirstValue,
|
||||
"user",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURICacheFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURICacheFlushesTotalKernel].FirstValue,
|
||||
"kernel",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURICacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURICacheHitsTotal].FirstValue+app[ServiceCacheURICacheMissesTotal].FirstValue,
|
||||
"user",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURICacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURICacheHitsTotalKernel].FirstValue+app[ServiceCacheURICacheMissesTotalKernel].FirstValue,
|
||||
"kernel",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURICacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURICacheHitsTotal].FirstValue,
|
||||
"user",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURICacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURICacheHitsTotalKernel].FirstValue,
|
||||
"kernel",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURIsCached,
|
||||
prometheus.GaugeValue,
|
||||
app[ServiceCacheURIsCached].FirstValue,
|
||||
"user",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURIsCached,
|
||||
prometheus.GaugeValue,
|
||||
app[ServiceCacheURIsCachedKernel].FirstValue,
|
||||
"kernel",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURIsCachedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURIsCachedTotal].FirstValue,
|
||||
"user",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURIsCachedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURIsCachedTotalKernel].FirstValue,
|
||||
"kernel",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURIsFlushedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURIsFlushedTotal].FirstValue,
|
||||
"user",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheURIsFlushedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheURIsFlushedTotalKernel].FirstValue,
|
||||
"kernel",
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheMetadataCached,
|
||||
prometheus.GaugeValue,
|
||||
app[ServiceCacheMetadataCached].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheMetadataCacheFlushes,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheMetadataCacheFlushes].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheMetadataCacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheMetaDataCacheHits].FirstValue+app[ServiceCacheMetaDataCacheMisses].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheMetadataCacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
0, // app[ServiceCacheMetadataCacheHitsTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheMetadataCachedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheMetadataCachedTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheMetadataFlushedTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheMetadataFlushedTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheOutputCacheActiveFlushedItems,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheOutputCacheActiveFlushedItems].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheOutputCacheItems,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheOutputCacheItems].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheOutputCacheMemoryUsage,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheOutputCacheMemoryUsage].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheOutputCacheQueriesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheOutputCacheHitsTotal].FirstValue+app[ServiceCacheOutputCacheMissesTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheOutputCacheHitsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheOutputCacheHitsTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheOutputCacheFlushedItemsTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheOutputCacheFlushedItemsTotal].FirstValue,
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.serviceCacheOutputCacheFlushesTotal,
|
||||
prometheus.CounterValue,
|
||||
app[ServiceCacheOutputCacheFlushesTotal].FirstValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/headers/slc"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/headers/slc"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/yusufpapurcu/wmi"
|
||||
)
|
||||
|
||||
const Name = "license"
|
||||
@@ -53,15 +53,11 @@ func (c *Collector) GetName() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
func (c *Collector) GetPerfCounter(_ *slog.Logger) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Close(_ *slog.Logger) error {
|
||||
func (c *Collector) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
c.licenseStatus = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "status"),
|
||||
"Status of windows license",
|
||||
@@ -74,20 +70,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *Collector) Collect(_ *types.ScrapeContext, logger *slog.Logger, ch chan<- prometheus.Metric) error {
|
||||
logger = logger.With(slog.String("collector", Name))
|
||||
if err := c.collect(ch); err != nil {
|
||||
logger.Error("failed collecting license metrics",
|
||||
slog.Any("err", err),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collect(ch chan<- prometheus.Metric) error {
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
status, err := slc.SLIsWindowsGenuineLocal()
|
||||
if err != nil {
|
||||
return err
|
||||
18
internal/collector/license/license_test.go
Normal file
18
internal/collector/license/license_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
//go:build windows
|
||||
|
||||
package license_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/collector/license"
|
||||
"github.com/prometheus-community/windows_exporter/internal/utils/testutils"
|
||||
)
|
||||
|
||||
func BenchmarkCollector(b *testing.B) {
|
||||
testutils.FuncBenchmarkCollector(b, license.Name, license.NewWithFlags)
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
testutils.TestCollector(t, license.New, nil)
|
||||
}
|
||||
22
internal/collector/logical_disk/const.go
Normal file
22
internal/collector/logical_disk/const.go
Normal file
@@ -0,0 +1,22 @@
|
||||
//go:build windows
|
||||
|
||||
package logical_disk
|
||||
|
||||
const (
|
||||
avgDiskReadQueueLength = "Avg. Disk Read Queue Length"
|
||||
avgDiskSecPerRead = "Avg. Disk sec/Read"
|
||||
avgDiskSecPerTransfer = "Avg. Disk sec/Transfer"
|
||||
avgDiskSecPerWrite = "Avg. Disk sec/Write"
|
||||
avgDiskWriteQueueLength = "Avg. Disk Write Queue Length"
|
||||
currentDiskQueueLength = "Current Disk Queue Length"
|
||||
freeSpace = "Free Megabytes"
|
||||
diskReadBytesPerSec = "Disk Read Bytes/sec"
|
||||
diskReadsPerSec = "Disk Reads/sec"
|
||||
diskWriteBytesPerSec = "Disk Write Bytes/sec"
|
||||
diskWritesPerSec = "Disk Writes/sec"
|
||||
percentDiskReadTime = "% Disk Read Time"
|
||||
percentDiskWriteTime = "% Disk Write Time"
|
||||
percentFreeSpace = "% Free Space"
|
||||
percentIdleTime = "% Idle Time"
|
||||
splitIOPerSec = "Split IO/Sec"
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user