mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-09 22:46:36 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be0037eda5 | ||
|
|
367fae95c4 | ||
|
|
96ffc3bf3f | ||
|
|
285c4cc5ea | ||
|
|
f07aceb0dd | ||
|
|
dcacce4577 | ||
|
|
fc5b3051fa | ||
|
|
1b2958a7cc | ||
|
|
a20e1854d1 | ||
|
|
fe21cb44f6 | ||
|
|
71ec0bd6a3 | ||
|
|
8bff623393 | ||
|
|
3eabd0a00c | ||
|
|
73186cde48 | ||
|
|
25e04fc947 | ||
|
|
6b7201856c | ||
|
|
608b83cfd8 | ||
|
|
40a42ca457 | ||
|
|
423c8a787e | ||
|
|
6cefbed7f7 | ||
|
|
5836a7dbf2 |
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
<!--
|
||||
Please give your PR a title in the form "area: short description". For example "cpu: reduce usage by 95%" or "docs: fix typo in installation.md".
|
||||
|
||||
|
||||
82
.github/workflows/release.yml
vendored
82
.github/workflows/release.yml
vendored
@@ -22,6 +22,7 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2022
|
||||
environment: build
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -32,13 +33,14 @@ jobs:
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
- name: Install WiX
|
||||
run: dotnet tool install --global wix
|
||||
run: |
|
||||
dotnet tool install --global wix --version 5.0.2
|
||||
|
||||
- name: Install WiX extensions
|
||||
run: |
|
||||
wix extension add -g WixToolset.Util.wixext
|
||||
wix extension add -g WixToolset.Ui.wixext
|
||||
wix extension add -g WixToolset.Firewall.wixext
|
||||
wix extension add -g WixToolset.Util.wixext/5.0.2
|
||||
wix extension add -g WixToolset.Ui.wixext/5.0.2
|
||||
wix extension add -g WixToolset.Firewall.wixext/5.0.2
|
||||
|
||||
- name: Install Build deps
|
||||
run: |
|
||||
@@ -68,6 +70,40 @@ jobs:
|
||||
|
||||
Get-ChildItem -Path output
|
||||
|
||||
- name: Sign build artifacts
|
||||
if: ${{ (github.event_name != 'pull_request' && github.repository == 'prometheus-community/windows_exporter') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'prometheus-community/windows_exporter') }}
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Version = Get-Content VERSION
|
||||
|
||||
$b64 = $env:CODE_SIGN_KEY
|
||||
$filename = 'windows_exporter_CodeSign.pfx'
|
||||
|
||||
$bytes = [Convert]::FromBase64String($b64)
|
||||
[IO.File]::WriteAllBytes($filename, $bytes)
|
||||
|
||||
$basePath = "C:\Program Files (x86)\Windows Kits\10\bin"
|
||||
$latestSigntool = Get-ChildItem -Path $basePath -Directory |
|
||||
Where-Object { $_.Name -match "^\d+\.\d+\.\d+\.\d+$" } |
|
||||
Sort-Object { [Version]$_.Name } -Descending |
|
||||
Select-Object -First 1 |
|
||||
ForEach-Object { Join-Path $_.FullName "x64\signtool.exe" }
|
||||
|
||||
if (Test-Path $latestSigntool) {
|
||||
Write-Output $latestSigntool
|
||||
} else {
|
||||
Write-Output "signtool.exe not found"
|
||||
}
|
||||
|
||||
foreach($Arch in "amd64", "arm64") {
|
||||
& $latestSigntool sign /v /tr "http://timestamp.digicert.com" /d "Prometheus exporter for Windows machines" /td SHA256 /fd SHA256 /a /f "windows_exporter_CodeSign.pfx" /p $env:CODE_SIGN_PASSWORD "output\windows_exporter-$Version-$Arch.exe"
|
||||
}
|
||||
|
||||
rm windows_exporter_CodeSign.pfx
|
||||
env:
|
||||
CODE_SIGN_KEY: ${{ secrets.CODE_SIGN_KEY }}
|
||||
CODE_SIGN_PASSWORD: ${{ secrets.CODE_SIGN_PASSWORD }}
|
||||
|
||||
- name: Build Release Artifacts
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
@@ -83,6 +119,40 @@ jobs:
|
||||
|
||||
promu checksum output\
|
||||
|
||||
- name: Sign installer artifacts
|
||||
if: ${{ (github.event_name != 'pull_request' && github.repository == 'prometheus-community/windows_exporter') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'prometheus-community/windows_exporter') }}
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Version = Get-Content VERSION
|
||||
|
||||
$b64 = $env:CODE_SIGN_KEY
|
||||
$filename = 'windows_exporter_CodeSign.pfx'
|
||||
|
||||
$bytes = [Convert]::FromBase64String($b64)
|
||||
[IO.File]::WriteAllBytes($filename, $bytes)
|
||||
|
||||
$basePath = "C:\Program Files (x86)\Windows Kits\10\bin"
|
||||
$latestSigntool = Get-ChildItem -Path $basePath -Directory |
|
||||
Where-Object { $_.Name -match "^\d+\.\d+\.\d+\.\d+$" } |
|
||||
Sort-Object { [Version]$_.Name } -Descending |
|
||||
Select-Object -First 1 |
|
||||
ForEach-Object { Join-Path $_.FullName "x64\signtool.exe" }
|
||||
|
||||
if (Test-Path $latestSigntool) {
|
||||
Write-Output $latestSigntool
|
||||
} else {
|
||||
Write-Output "signtool.exe not found"
|
||||
}
|
||||
|
||||
foreach($Arch in "amd64", "arm64") {
|
||||
& $latestSigntool sign /v /tr "http://timestamp.digicert.com" /d "Prometheus exporter for Windows machines" /td SHA256 /fd SHA256 /a /f "windows_exporter_CodeSign.pfx" /p $env:CODE_SIGN_PASSWORD "output\windows_exporter-$Version-$Arch.msi"
|
||||
}
|
||||
|
||||
rm windows_exporter_CodeSign.pfx
|
||||
env:
|
||||
CODE_SIGN_KEY: ${{ secrets.CODE_SIGN_KEY }}
|
||||
CODE_SIGN_PASSWORD: ${{ secrets.CODE_SIGN_PASSWORD }}
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -103,6 +173,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
env:
|
||||
DOCKER_BUILD_SUMMARY: false
|
||||
DOCKER_BUILD_RECORD_UPLOAD: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -165,3 +238,4 @@ jobs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: windows/amd64
|
||||
annotations: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
2
.github/workflows/stale-close.yml
vendored
2
.github/workflows/stale-close.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# opt out of defaults to avoid marking issues as stale and closing them
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# opt out of defaults to avoid marking issues as stale and closing them
|
||||
|
||||
@@ -88,7 +88,7 @@ windows_exporter accepts flags to configure certain behaviours. The ones configu
|
||||
| `--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.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 |
|
||||
@@ -100,6 +100,9 @@ windows_exporter accepts flags to configure certain behaviours. The ones configu
|
||||
|
||||
The latest release can be downloaded from the [releases page](https://github.com/prometheus-community/windows_exporter/releases).
|
||||
|
||||
All binaries and installation packages are signed with an self-signed certificate. The public key can be found [here](https://github.com/prometheus-community/windows_exporter/blob/master/installer/codesign.cer).
|
||||
Once import into the trusted root certificate store, the binaries and installation packages will be trusted.
|
||||
|
||||
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.
|
||||
|
||||
@@ -33,6 +33,9 @@ var (
|
||||
|
||||
// stopCh is a channel to send a signal to the service manager that the service is stopping.
|
||||
stopCh = make(chan struct{})
|
||||
|
||||
// serviceManagerFinishedCh is a channel to send a signal to the main function that the service manager has stopped the service.
|
||||
serviceManagerFinishedCh = make(chan struct{})
|
||||
)
|
||||
|
||||
// IsService variable declaration allows initiating time-sensitive components like registering the Windows service
|
||||
@@ -49,30 +52,31 @@ var (
|
||||
//
|
||||
//nolint:gochecknoglobals
|
||||
var IsService = func() bool {
|
||||
defer func() {
|
||||
go func() {
|
||||
err := svc.Run(serviceName, &windowsExporterService{})
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_ = logToEventToLog(windows.EVENTLOG_ERROR_TYPE, fmt.Sprintf("failed to start service: %v", err))
|
||||
}()
|
||||
}()
|
||||
|
||||
var err error
|
||||
|
||||
isService, err := svc.IsWindowsService()
|
||||
if err != nil {
|
||||
_ = logToEventToLog(windows.EVENTLOG_ERROR_TYPE, fmt.Sprintf("failed to detect service: %v", err))
|
||||
//nolint:gosec
|
||||
_ = os.WriteFile("C:\\Program Files\\windows_exporter\\start-service.error.log", []byte(fmt.Sprintf("failed to detect service: %v", err)), 0o644)
|
||||
|
||||
exitCodeCh <- 1
|
||||
return false
|
||||
}
|
||||
|
||||
if !isService {
|
||||
return false
|
||||
}
|
||||
|
||||
defer func() {
|
||||
go func() {
|
||||
err := svc.Run(serviceName, &windowsExporterService{})
|
||||
if err != nil {
|
||||
_ = logToEventToLog(windows.EVENTLOG_ERROR_TYPE, fmt.Sprintf("failed to start service: %v", err))
|
||||
}
|
||||
|
||||
serviceManagerFinishedCh <- struct{}{}
|
||||
}()
|
||||
}()
|
||||
|
||||
if err := logToEventToLog(windows.EVENTLOG_INFORMATION_TYPE, "attempting to start exporter service"); err != nil {
|
||||
//nolint:gosec
|
||||
_ = os.WriteFile("C:\\Program Files\\windows_exporter\\start-service.error.log", []byte(fmt.Sprintf("failed sent log to event log: %v", err)), 0o644)
|
||||
@@ -122,7 +126,7 @@ func (s *windowsExporterService) Execute(_ []string, r <-chan svc.ChangeRequest,
|
||||
|
||||
// logToEventToLog logs a message to the Windows event log.
|
||||
func logToEventToLog(eType uint16, msg string) error {
|
||||
eventLog, err := eventlog.Open("windows_exporter")
|
||||
eventLog, err := eventlog.Open(serviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open event log: %w", err)
|
||||
}
|
||||
@@ -130,15 +134,15 @@ func logToEventToLog(eType uint16, msg string) error {
|
||||
_ = eventLog.Close()
|
||||
}(eventLog)
|
||||
|
||||
p, err := windows.UTF16PtrFromString(msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error convert string to UTF-16: %w", err)
|
||||
switch eType {
|
||||
case windows.EVENTLOG_ERROR_TYPE:
|
||||
err = eventLog.Error(102, msg)
|
||||
case windows.EVENTLOG_WARNING_TYPE:
|
||||
err = eventLog.Warning(101, msg)
|
||||
case windows.EVENTLOG_INFORMATION_TYPE:
|
||||
err = eventLog.Info(100, msg)
|
||||
}
|
||||
|
||||
zero := uint16(0)
|
||||
ss := []*uint16{p, &zero, &zero, &zero, &zero, &zero, &zero, &zero, &zero}
|
||||
|
||||
err = windows.ReportEvent(eventLog.Handle, eType, 0, 3299, 0, 9, 0, &ss[0], nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error report event: %w", err)
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func main() {
|
||||
exitCodeCh <- exitCode
|
||||
|
||||
// Wait for the service control manager to signal that we are done.
|
||||
<-stopCh
|
||||
<-serviceManagerFinishedCh
|
||||
}
|
||||
|
||||
func run() int {
|
||||
@@ -163,11 +163,6 @@ func run() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// NOTE: This is temporary fix for issue #1092, calling kingpin.Parse
|
||||
// twice makes slices flags duplicate its value, this clean up
|
||||
// the first parse before the second call.
|
||||
*webConfig.WebListenAddresses = (*webConfig.WebListenAddresses)[1:]
|
||||
|
||||
// Parse flags once more to include those discovered in configuration file(s).
|
||||
if _, err = app.Parse(os.Args[1:]); err != nil {
|
||||
logger.ErrorContext(ctx, "failed to parse CLI args from YAML file",
|
||||
@@ -177,6 +172,12 @@ func run() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// NOTE: This is temporary fix for issue #1092, calling kingpin.Parse
|
||||
// twice makes slices flags duplicate its value, this clean up
|
||||
// the first parse before the second call.
|
||||
slices.Sort(*webConfig.WebListenAddresses)
|
||||
*webConfig.WebListenAddresses = slices.Clip(slices.Compact(*webConfig.WebListenAddresses))
|
||||
|
||||
logger, err = log.New(logConfig)
|
||||
if err != nil {
|
||||
//nolint:sloglint // we do not have an logger yet
|
||||
@@ -325,7 +326,7 @@ func setPriorityWindows(logger *slog.Logger, pid int, priority string) error {
|
||||
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 {
|
||||
if !ok || winPriority == windows.NORMAL_PRIORITY_CLASS {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2,49 +2,177 @@
|
||||
|
||||
The dhcp collector exposes DHCP Server metrics
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `dhcp`
|
||||
Data source | Perflib
|
||||
Classes | `DHCP Server`
|
||||
Enabled by default? | No
|
||||
| | |
|
||||
|---------------------|---------------|
|
||||
| Metric name prefix | `dhcp` |
|
||||
| Data source | Perflib |
|
||||
| Classes | `DHCP Server` |
|
||||
| Enabled by default? | No |
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
### `--collector.dhcp.enabled`
|
||||
|
||||
Comma-separated list of collectors to use. Defaults to all, if not specified.
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`packets_received_total` | Total number of packets received by the DHCP server | counter | None
|
||||
`duplicates_dropped_total` | Total number of duplicate packets received by the DHCP server | counter | None
|
||||
`packets_expired_total` | Total number of packets expired in the DHCP server message queue | counter | None
|
||||
`active_queue_length` | Number of packets in the processing queue of the DHCP server | gauge | None
|
||||
`conflict_check_queue_length` | Number of packets in the DHCP server queue waiting on conflict detection (ping) | gauge | None
|
||||
`discovers_total` | Total DHCP Discovers received by the DHCP server | counter | None
|
||||
`offers_total` | Total DHCP Offers sent by the DHCP server | counter | None
|
||||
`requests_total` | Total DHCP Requests received by the DHCP server | counter | None
|
||||
`informs_total` | Total DHCP Informs received by the DHCP server | counter | None
|
||||
`acks_total` | Total DHCP Acks sent by the DHCP server | counter | None
|
||||
`nacks_total` | Total DHCP Nacks sent by the DHCP server | counter | None
|
||||
`declines_total` | Total DHCP Declines received by the DHCP server | counter | None
|
||||
`releases_total` | Total DHCP Releases received by the DHCP server | counter | None
|
||||
`offer_queue_length` | Number of packets in the offer queue of the DHCP server | gauge | None
|
||||
`denied_due_to_match_total` | Total number of DHCP requests denied, based on matches from the Deny List | gauge | None
|
||||
`denied_due_to_nonmatch_total` | Total number of DHCP requests denied, based on non-matches from the Allow List | gauge | None
|
||||
`failover_bndupd_sent_total` | Number of DHCP failover Binding Update messages sent | counter | None
|
||||
`failover_bndupd_received_total` | Number of DHCP failover Binding Update messages received | counter | None
|
||||
`failover_bndack_sent_total` | Number of DHCP failover Binding Ack messages sent | counter | None
|
||||
`failover_bndack_received_total` | Number of DHCP failover Binding Ack messages received | counter | None
|
||||
`failover_bndupd_pending_in_outbound_queue` | Number of pending outbound DHCP failover Binding Update messages | counter | None
|
||||
`failover_transitions_communicationinterrupted_state_total` | Total number of transitions into COMMUNICATION INTERRUPTED state | counter | None
|
||||
`failover_transitions_partnerdown_state_total` | Total number of transitions into PARTNER DOWN state | counter | None
|
||||
`failover_transitions_recover_total` | Total number of transitions into RECOVER state | counter | None
|
||||
`failover_bndupd_dropped_total` | Total number of DHCP faileover Binding Updates dropped | counter | None
|
||||
| Name | Description | Type | Labels |
|
||||
|--------------------------------------------------------------------------|--------------------------------------------------------------------------------|---------|-----------------------------------------------------|
|
||||
| `windows_dhcp_ack_total` | Total DHCP Acks sent by the DHCP server | counter | None |
|
||||
| `windows_dhcp_denied_due_to_match_total` | Total number of DHCP requests denied, based on matches from the Deny List | gauge | None |
|
||||
| `windows_dhcp_denied_due_to_nonmatch_total` | Total number of DHCP requests denied, based on non-matches from the Allow List | gauge | None |
|
||||
| `windows_dhcp_declines_total` | Total DHCP Declines received by the DHCP server | counter | None |
|
||||
| `windows_dhcp_discovers_total` | Total DHCP Discovers received by the DHCP server | counter | None |
|
||||
| `windows_dhcp_failover_bndack_received_total` | Number of DHCP failover Binding Ack messages received | counter | None |
|
||||
| `windows_dhcp_failover_bndack_sent_total` | Number of DHCP failover Binding Ack messages sent | counter | None |
|
||||
| `windows_dhcp_failover_bndupd_dropped_total` | Total number of DHCP failover Binding Updates dropped | counter | None |
|
||||
| `windows_dhcp_failover_bndupd_received_total` | Number of DHCP failover Binding Update messages received | counter | None |
|
||||
| `windows_dhcp_failover_bndupd_sent_total` | Number of DHCP failover Binding Update messages sent | counter | None |
|
||||
| `windows_dhcp_failover_bndupd_pending_in_outbound_queue` | Number of pending outbound DHCP failover Binding Update messages | counter | None |
|
||||
| `windows_dhcp_failover_transitions_communicationinterrupted_state_total` | Total number of transitions into COMMUNICATION INTERRUPTED state | counter | None |
|
||||
| `windows_dhcp_failover_transitions_partnerdown_state_total` | Total number of transitions into PARTNER DOWN state | counter | None |
|
||||
| `windows_dhcp_failover_transitions_recover_total` | Total number of transitions into RECOVER state | counter | None |
|
||||
| `windows_dhcp_informs_total` | Total DHCP Informs received by the DHCP server | counter | None |
|
||||
| `windows_dhcp_nacks_total` | Total DHCP Nacks sent by the DHCP server | counter | None |
|
||||
| `windows_dhcp_offers_total` | Total DHCP Offers sent by the DHCP server | counter | None |
|
||||
| `windows_dhcp_packets_expired_total` | Total number of packets expired in the DHCP server message queue | counter | None |
|
||||
| `windows_dhcp_packets_received_total` | Total number of packets received by the DHCP server | counter | None |
|
||||
| `windows_dhcp_pending_offers_total` | Total number of pending offers in the DHCP server | counter | None |
|
||||
| `windows_dhcp_releases_total` | Total DHCP Releases received by the DHCP server | counter | None |
|
||||
| `windows_dhcp_requests_total` | Total DHCP Requests received by the DHCP server | counter | None |
|
||||
| `windows_dhcp_scope_addresses_free_on_this_server` | DHCP Scope free addresses on this server | gauge | `scope` |
|
||||
| `windows_dhcp_scope_addresses_free_on_partner_server` | DHCP Scope free addresses on partner server | gauge | `scope` |
|
||||
| `windows_dhcp_scope_addresses_free` | DHCP Scope free addresses | gauge | `scope` |
|
||||
| `windows_dhcp_scope_addresses_in_use_on_this_server` | DHCP Scope addresses in use on this server | gauge | `scope` |
|
||||
| `windows_dhcp_scope_addresses_in_use_on_partner_server` | DHCP Scope addresses in use on partner server | gauge | `scope` |
|
||||
| `windows_dhcp_scope_addresses_in_use` | DHCP Scope addresses in use | gauge | `scope` |
|
||||
| `windows_dhcp_scope_info` | DHCP Scope information | gauge | `name`, `superscope_name`, `superscope_id`, `scope` |
|
||||
| `windows_dhcp_scope_pending_offers` | DHCP Scope pending offers | gauge | `scope` |
|
||||
| `windows_dhcp_scope_reserved_address` | DHCP Scope reserved addresses | gauge | `scope` |
|
||||
| `windows_dhcp_scope_state` | DHCP Scope state | gauge | `scope`, `state` |
|
||||
|
||||
|
||||
### Example metric
|
||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||
```
|
||||
# HELP windows_dhcp_acks_total Total DHCP Acks sent by the DHCP server (AcksTotal)
|
||||
# TYPE windows_dhcp_acks_total counter
|
||||
windows_dhcp_acks_total 0
|
||||
# HELP windows_dhcp_active_queue_length Number of packets in the processing queue of the DHCP server (ActiveQueueLength)
|
||||
# TYPE windows_dhcp_active_queue_length gauge
|
||||
windows_dhcp_active_queue_length 0
|
||||
# HELP windows_dhcp_conflict_check_queue_length Number of packets in the DHCP server queue waiting on conflict detection (ping). (ConflictCheckQueueLength)
|
||||
# TYPE windows_dhcp_conflict_check_queue_length gauge
|
||||
windows_dhcp_conflict_check_queue_length 0
|
||||
# HELP windows_dhcp_declines_total Total DHCP Declines received by the DHCP server (DeclinesTotal)
|
||||
# TYPE windows_dhcp_declines_total counter
|
||||
windows_dhcp_declines_total 0
|
||||
# HELP windows_dhcp_denied_due_to_match_total Total number of DHCP requests denied, based on matches from the Deny list (DeniedDueToMatch)
|
||||
# TYPE windows_dhcp_denied_due_to_match_total counter
|
||||
windows_dhcp_denied_due_to_match_total 0
|
||||
# HELP windows_dhcp_denied_due_to_nonmatch_total Total number of DHCP requests denied, based on non-matches from the Allow list (DeniedDueToNonMatch)
|
||||
# TYPE windows_dhcp_denied_due_to_nonmatch_total counter
|
||||
windows_dhcp_denied_due_to_nonmatch_total 0
|
||||
# HELP windows_dhcp_discovers_total Total DHCP Discovers received by the DHCP server (DiscoversTotal)
|
||||
# TYPE windows_dhcp_discovers_total counter
|
||||
windows_dhcp_discovers_total 0
|
||||
# HELP windows_dhcp_duplicates_dropped_total Total number of duplicate packets received by the DHCP server (DuplicatesDroppedTotal)
|
||||
# TYPE windows_dhcp_duplicates_dropped_total counter
|
||||
windows_dhcp_duplicates_dropped_total 0
|
||||
# HELP windows_dhcp_failover_bndack_received_total Number of DHCP fail over Binding Ack messages received (FailoverBndackReceivedTotal)
|
||||
# TYPE windows_dhcp_failover_bndack_received_total counter
|
||||
windows_dhcp_failover_bndack_received_total 0
|
||||
# HELP windows_dhcp_failover_bndack_sent_total Number of DHCP fail over Binding Ack messages sent (FailoverBndackSentTotal)
|
||||
# TYPE windows_dhcp_failover_bndack_sent_total counter
|
||||
windows_dhcp_failover_bndack_sent_total 0
|
||||
# HELP windows_dhcp_failover_bndupd_dropped_total Total number of DHCP fail over Binding Updates dropped (FailoverBndupdDropped)
|
||||
# TYPE windows_dhcp_failover_bndupd_dropped_total counter
|
||||
windows_dhcp_failover_bndupd_dropped_total 0
|
||||
# HELP windows_dhcp_failover_bndupd_pending_in_outbound_queue Number of pending outbound DHCP fail over Binding Update messages (FailoverBndupdPendingOutboundQueue)
|
||||
# TYPE windows_dhcp_failover_bndupd_pending_in_outbound_queue gauge
|
||||
windows_dhcp_failover_bndupd_pending_in_outbound_queue 0
|
||||
# HELP windows_dhcp_failover_bndupd_received_total Number of DHCP fail over Binding Update messages received (FailoverBndupdReceivedTotal)
|
||||
# TYPE windows_dhcp_failover_bndupd_received_total counter
|
||||
windows_dhcp_failover_bndupd_received_total 0
|
||||
# HELP windows_dhcp_failover_bndupd_sent_total Number of DHCP fail over Binding Update messages sent (FailoverBndupdSentTotal)
|
||||
# TYPE windows_dhcp_failover_bndupd_sent_total counter
|
||||
windows_dhcp_failover_bndupd_sent_total 0
|
||||
# HELP windows_dhcp_failover_transitions_communicationinterrupted_state_total Total number of transitions into COMMUNICATION INTERRUPTED state (FailoverTransitionsCommunicationinterruptedState)
|
||||
# TYPE windows_dhcp_failover_transitions_communicationinterrupted_state_total counter
|
||||
windows_dhcp_failover_transitions_communicationinterrupted_state_total 0
|
||||
# HELP windows_dhcp_failover_transitions_partnerdown_state_total Total number of transitions into PARTNER DOWN state (FailoverTransitionsPartnerdownState)
|
||||
# TYPE windows_dhcp_failover_transitions_partnerdown_state_total counter
|
||||
windows_dhcp_failover_transitions_partnerdown_state_total 0
|
||||
# HELP windows_dhcp_failover_transitions_recover_total Total number of transitions into RECOVER state (FailoverTransitionsRecoverState)
|
||||
# TYPE windows_dhcp_failover_transitions_recover_total counter
|
||||
windows_dhcp_failover_transitions_recover_total 0
|
||||
# HELP windows_dhcp_informs_total Total DHCP Informs received by the DHCP server (InformsTotal)
|
||||
# TYPE windows_dhcp_informs_total counter
|
||||
windows_dhcp_informs_total 0
|
||||
# HELP windows_dhcp_nacks_total Total DHCP Nacks sent by the DHCP server (NacksTotal)
|
||||
# TYPE windows_dhcp_nacks_total counter
|
||||
windows_dhcp_nacks_total 0
|
||||
# HELP windows_dhcp_offer_queue_length Number of packets in the offer queue of the DHCP server (OfferQueueLength)
|
||||
# TYPE windows_dhcp_offer_queue_length gauge
|
||||
windows_dhcp_offer_queue_length 0
|
||||
# HELP windows_dhcp_offers_total Total DHCP Offers sent by the DHCP server (OffersTotal)
|
||||
# TYPE windows_dhcp_offers_total counter
|
||||
windows_dhcp_offers_total 0
|
||||
# HELP windows_dhcp_packets_expired_total Total number of packets expired in the DHCP server message queue (PacketsExpiredTotal)
|
||||
# TYPE windows_dhcp_packets_expired_total counter
|
||||
windows_dhcp_packets_expired_total 0
|
||||
# HELP windows_dhcp_packets_received_total Total number of packets received by the DHCP server (PacketsReceivedTotal)
|
||||
# TYPE windows_dhcp_packets_received_total counter
|
||||
windows_dhcp_packets_received_total 0
|
||||
# HELP windows_dhcp_releases_total Total DHCP Releases received by the DHCP server (ReleasesTotal)
|
||||
# TYPE windows_dhcp_releases_total counter
|
||||
windows_dhcp_releases_total 0
|
||||
# HELP windows_dhcp_requests_total Total DHCP Requests received by the DHCP server (RequestsTotal)
|
||||
# TYPE windows_dhcp_requests_total counter
|
||||
windows_dhcp_requests_total 0
|
||||
# HELP windows_dhcp_scope_addresses_free_total DHCP Scope free addresses
|
||||
# TYPE windows_dhcp_scope_addresses_free_total gauge
|
||||
windows_dhcp_scope_addresses_free_total{scope="10.11.12.0/25"} 0
|
||||
windows_dhcp_scope_addresses_free_total{scope="172.16.0.0/24"} 0
|
||||
windows_dhcp_scope_addresses_free_total{scope="192.168.0.0/24"} 231
|
||||
# HELP windows_dhcp_scope_addresses_in_use_total DHCP Scope addresses in use
|
||||
# TYPE windows_dhcp_scope_addresses_in_use_total gauge
|
||||
windows_dhcp_scope_addresses_in_use_total{scope="10.11.12.0/25"} 0
|
||||
windows_dhcp_scope_addresses_in_use_total{scope="172.16.0.0/24"} 0
|
||||
windows_dhcp_scope_addresses_in_use_total{scope="192.168.0.0/24"} 0
|
||||
# HELP windows_dhcp_scope_info DHCP Scope information
|
||||
# TYPE windows_dhcp_scope_info gauge
|
||||
windows_dhcp_scope_info{name="SUBSUPERSCOPE",scope="172.16.0.0/24",superscope_id="2",superscope_name="SUPERSCOPE"} 1
|
||||
windows_dhcp_scope_info{name="TEST",scope="192.168.0.0/24",superscope_id="0",superscope_name=""} 1
|
||||
windows_dhcp_scope_info{name="TEST2",scope="10.11.12.0/25",superscope_id="2",superscope_name="SUPERSCOPE"} 1
|
||||
# HELP windows_dhcp_scope_pending_offers_total DHCP Scope pending offers
|
||||
# TYPE windows_dhcp_scope_pending_offers_total gauge
|
||||
windows_dhcp_scope_pending_offers_total{scope="10.11.12.0/25"} 0
|
||||
windows_dhcp_scope_pending_offers_total{scope="172.16.0.0/24"} 0
|
||||
windows_dhcp_scope_pending_offers_total{scope="192.168.0.0/24"} 0
|
||||
# HELP windows_dhcp_scope_reserved_address_total DHCP Scope reserved addresses
|
||||
# TYPE windows_dhcp_scope_reserved_address_total gauge
|
||||
windows_dhcp_scope_reserved_address_total{scope="10.11.12.0/25"} 0
|
||||
windows_dhcp_scope_reserved_address_total{scope="172.16.0.0/24"} 0
|
||||
windows_dhcp_scope_reserved_address_total{scope="192.168.0.0/24"} 2
|
||||
# HELP windows_dhcp_scope_state DHCP Scope state
|
||||
# TYPE windows_dhcp_scope_state gauge
|
||||
windows_dhcp_scope_state{scope="10.11.12.0/25",state="Disabled"} 1
|
||||
windows_dhcp_scope_state{scope="10.11.12.0/25",state="DisabledSwitched"} 0
|
||||
windows_dhcp_scope_state{scope="10.11.12.0/25",state="Enabled"} 0
|
||||
windows_dhcp_scope_state{scope="10.11.12.0/25",state="EnabledSwitched"} 0
|
||||
windows_dhcp_scope_state{scope="10.11.12.0/25",state="InvalidState"} 0
|
||||
windows_dhcp_scope_state{scope="172.16.0.0/24",state="Disabled"} 1
|
||||
windows_dhcp_scope_state{scope="172.16.0.0/24",state="DisabledSwitched"} 0
|
||||
windows_dhcp_scope_state{scope="172.16.0.0/24",state="Enabled"} 0
|
||||
windows_dhcp_scope_state{scope="172.16.0.0/24",state="EnabledSwitched"} 0
|
||||
windows_dhcp_scope_state{scope="172.16.0.0/24",state="InvalidState"} 0
|
||||
windows_dhcp_scope_state{scope="192.168.0.0/24",state="Disabled"} 0
|
||||
windows_dhcp_scope_state{scope="192.168.0.0/24",state="DisabledSwitched"} 0
|
||||
windows_dhcp_scope_state{scope="192.168.0.0/24",state="Enabled"} 1
|
||||
windows_dhcp_scope_state{scope="192.168.0.0/24",state="EnabledSwitched"} 0
|
||||
windows_dhcp_scope_state{scope="192.168.0.0/24",state="InvalidState"} 0
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
_This collector does not yet have any useful queries added, we would appreciate your help adding them!_
|
||||
|
||||
@@ -19,6 +19,10 @@ If given, an interface name needs to match the include regexp in order for the c
|
||||
|
||||
If given, an interface name needs to *not* match the exclude regexp in order for the corresponding metrics to be reported
|
||||
|
||||
### `--collector.net.enabled`
|
||||
|
||||
Comma-separated list of collectors to use. Defaults to all, if not specified.
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
|
||||
@@ -10,7 +10,9 @@ The netframework collector exposes metrics about dotnet framework.
|
||||
|
||||
## Flags
|
||||
|
||||
None
|
||||
### `--collector.netframework.enabled`
|
||||
|
||||
Comma-separated list of collectors to use. Defaults to all, if not specified.
|
||||
|
||||
## Metrics
|
||||
|
||||
|
||||
29
go.mod
29
go.mod
@@ -5,16 +5,15 @@ go 1.23
|
||||
require (
|
||||
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/bmatcuk/doublestar/v4 v4.8.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/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/client_golang v1.21.0-rc.0
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.61.0
|
||||
github.com/prometheus/exporter-toolkit v0.13.2
|
||||
github.com/prometheus/common v0.62.0
|
||||
github.com/prometheus/exporter-toolkit v0.14.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/sys v0.29.0
|
||||
golang.org/x/sys v0.30.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
@@ -23,7 +22,7 @@ require (
|
||||
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.4 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.5 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
@@ -43,13 +42,13 @@ require (
|
||||
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.31.0 // indirect
|
||||
golang.org/x/net v0.32.0 // indirect
|
||||
golang.org/x/oauth2 v0.24.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect
|
||||
google.golang.org/grpc v1.68.0 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/oauth2 v0.26.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
58
go.sum
58
go.sum
@@ -10,15 +10,15 @@ github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vS
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
|
||||
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/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=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups/v3 v3.0.4 h1:2fs7l3P0Qxb1nKWuJNFiwhp2CqiKzho71DQkDrHJIo4=
|
||||
github.com/containerd/cgroups/v3 v3.0.4/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
|
||||
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
|
||||
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
@@ -66,8 +66,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
@@ -92,15 +90,15 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.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_golang v1.21.0-rc.0 h1:bR+RxBlwcr4q8hXkgSOA/J18j6n0/qH0Gb0DH+8c+RY=
|
||||
github.com/prometheus/client_golang v1.21.0-rc.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
|
||||
github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
|
||||
github.com/prometheus/exporter-toolkit v0.13.2 h1:Z02fYtbqTMy2i/f+xZ+UK5jy/bl1Ex3ndzh06T/Q9DQ=
|
||||
github.com/prometheus/exporter-toolkit v0.13.2/go.mod h1:tCqnfx21q6qN1KA4U3Bfb8uWzXfijIrJz3/kTIqMV7g=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg=
|
||||
github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA=
|
||||
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=
|
||||
@@ -128,8 +126,8 @@ 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.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
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=
|
||||
@@ -145,30 +143,30 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
|
||||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
|
||||
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
||||
golang.org/x/oauth2 v0.26.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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/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-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.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/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=
|
||||
@@ -186,15 +184,15 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||
google.golang.org/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.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/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=
|
||||
@@ -204,8 +202,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.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/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=
|
||||
|
||||
@@ -28,7 +28,7 @@ Copy-Item -Force $PathToExecutable Work/windows_exporter.exe
|
||||
Write-Verbose "Creating windows_exporter-${Version}-${Arch}.msi"
|
||||
$wixArch = @{"amd64" = "x64"; "arm64" = "arm64"}[$Arch]
|
||||
|
||||
Invoke-Expression "wix build -arch $wixArch -o .\windows_exporter-$($Version)-$($Arch).msi .\files.wxs .\main.wxs -d ProductName=windows_exporter -d Version=$($MsiVersion) -ext WixToolset.Firewall.wixext -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext"
|
||||
Invoke-Expression "wix build -sw1149 -arch $wixArch -o .\windows_exporter-$($Version)-$($Arch).msi .\files.wxs .\main.wxs -d ProductName=windows_exporter -d Version=$($MsiVersion) -ext WixToolset.Firewall.wixext -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext"
|
||||
|
||||
Write-Verbose "Done!"
|
||||
Pop-Location
|
||||
|
||||
BIN
installer/codesign.cer
Normal file
BIN
installer/codesign.cer
Normal file
Binary file not shown.
@@ -44,6 +44,12 @@
|
||||
<ServiceDependency Id="wmiApSrv" />
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="ServiceStateControl" Name="windows_exporter" Remove="uninstall" Start="install" Stop="both"/>
|
||||
<!-- The "Name" field must match the argument to eventlog.Open() -->
|
||||
<util:EventSource Log="Application" Name="windows_exporter"
|
||||
EventMessageFile="%SystemRoot%\System32\EventCreate.exe"
|
||||
SupportsErrors="yes"
|
||||
SupportsInformationals="yes"
|
||||
SupportsWarnings="yes"/>
|
||||
</Component>
|
||||
<Component Id="CreateTextfileDirectory" Directory="textfile_inputs" Guid="d03ef58a-9cbf-4165-ad39-d143e9b27e14">
|
||||
<CreateFolder />
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
Property="OLDERVERSIONBEINGUPGRADED" />
|
||||
</Upgrade>
|
||||
|
||||
<CustomAction Id="CheckExtraFlags"
|
||||
Error="The parameter '--config.file' must not be included in EXTRA_FLAGS. Use CONFIG_FILE instead. Please remove it and try again." />
|
||||
|
||||
<CustomAction Id="set_maintenance" Property="MAINTENANCE" Value="true" />
|
||||
|
||||
<!-- Set to reinstall all features. -->
|
||||
@@ -54,12 +57,12 @@
|
||||
<CustomAction Id="set_reinstallmode_property"
|
||||
Property="REINSTALLMODE"
|
||||
Value="amus" />
|
||||
<!-- START CUSTOM ACTION FOR CONFIG FILE CREATION -->
|
||||
<SetProperty
|
||||
Id="CreateConfigFile"
|
||||
Value=""[%ComSpec]" /c TYPE NUL >>"[ConfigFile_NonDefault][ConfigFile_Default]""
|
||||
Before="CreateConfigFile"
|
||||
Sequence="execute"
|
||||
Condition="ConfigFile_NonDefault OR ConfigFile_Default"
|
||||
/>
|
||||
<CustomAction
|
||||
Id="CreateConfigFile"
|
||||
@@ -69,6 +72,24 @@
|
||||
Return="check"
|
||||
Impersonate="no"
|
||||
/>
|
||||
<!-- END CUSTOM ACTION FOR CONFIG FILE CREATION -->
|
||||
|
||||
<!-- START CUSTOM ACTION FOR KILLING THE PROCESS -->
|
||||
<SetProperty
|
||||
Id="KillProcess"
|
||||
Value=""[WindowsFolder]\System32\taskkill.exe" /T /F /IM windows_exporter.exe"
|
||||
Before="KillProcess"
|
||||
Sequence="execute"
|
||||
/>
|
||||
<CustomAction
|
||||
Id="KillProcess"
|
||||
BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)"
|
||||
DllEntry="WixQuietExec"
|
||||
Execute="deferred"
|
||||
Return="ignore"
|
||||
Impersonate="no"
|
||||
/>
|
||||
<!-- END CUSTOM ACTION FOR KILLING THE PROCESS -->
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<!-- Set REINSTALL=all and REINSTALLMODE=amus if the user reruns the
|
||||
@@ -78,6 +99,10 @@
|
||||
<Custom Action="set_reinstall_all_property" Before="set_reinstallmode_property" Condition="MAINTENANCE"/>
|
||||
<Custom Action="set_reinstallmode_property" Before="LaunchConditions" Condition="MAINTENANCE"/>
|
||||
<Custom Action="CreateConfigFile" Before="InstallServices" Condition="ConfigFile_NonDefault OR ConfigFile_Default" />
|
||||
<Custom Action="KillProcess" Before="RemoveFiles" />
|
||||
|
||||
<Custom Action="CheckExtraFlags" Before="InstallInitialize"
|
||||
Condition="EXTRA_FLAGS AND (EXTRA_FLAGS><"--config.file")" />
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<Media Id="1" Cabinet="windows_exporter.cab" EmbedCab="yes" />
|
||||
@@ -90,9 +115,10 @@
|
||||
<SetProperty Id="ExtraFlags" After="InstallFiles" Sequence="execute" Value="[EXTRA_FLAGS]" Condition="EXTRA_FLAGS" />
|
||||
|
||||
<Property Id="CONFIG_FILE" Secure="yes" Value="config.yaml" />
|
||||
<SetProperty Id="ConfigFile_NonDefault" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND CONFIG_FILE<>"config.yaml"" />
|
||||
<SetProperty Id="ConfigFile_Remote" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND (CONFIG_FILE<<"http://" OR CONFIG_FILE<<"https://")" />
|
||||
<SetProperty Id="ConfigFile_NonDefault" After="InstallFiles" Sequence="execute" Value="[CONFIG_FILE]" Condition="CONFIG_FILE AND CONFIG_FILE<>"config.yaml" AND NOT (CONFIG_FILE<<"http://" OR CONFIG_FILE<<"https://")" />
|
||||
<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" />
|
||||
<SetProperty Id="ConfigFileFlag" After="InstallFiles" Sequence="execute" Value="--config.file="[ConfigFile_Remote][ConfigFile_NonDefault][ConfigFile_Default]"" Condition="ConfigFile_Remote OR 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" />
|
||||
|
||||
@@ -37,7 +37,7 @@ type Collector struct {
|
||||
config Config
|
||||
|
||||
// physicalMemoryBytes
|
||||
// Deprecated: Use windows_physical_memory_total_bytes instead
|
||||
// Deprecated: Use windows_memory_physical_total_bytes instead
|
||||
physicalMemoryBytes *prometheus.Desc
|
||||
// logicalProcessors
|
||||
// Deprecated: Use windows_cpu_logical_processor instead
|
||||
@@ -85,7 +85,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
)
|
||||
c.physicalMemoryBytes = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "physical_memory_bytes"),
|
||||
"Deprecated: Use windows_physical_memory_total_bytes instead",
|
||||
"Deprecated: Use windows_memory_physical_total_bytes instead",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
@@ -16,22 +16,39 @@
|
||||
package dhcp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/headers/dhcpsapi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const Name = "dhcp"
|
||||
const (
|
||||
Name = "dhcp"
|
||||
|
||||
type Config struct{}
|
||||
subCollectorServerMetrics = "server_metrics"
|
||||
subCollectorScopeMetrics = "scope_metrics"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var ConfigDefaults = Config{}
|
||||
var ConfigDefaults = Config{
|
||||
CollectorsEnabled: []string{
|
||||
subCollectorServerMetrics,
|
||||
subCollectorScopeMetrics,
|
||||
},
|
||||
}
|
||||
|
||||
// A Collector is a Prometheus Collector perflib DHCP metrics.
|
||||
type Collector struct {
|
||||
@@ -65,6 +82,17 @@ type Collector struct {
|
||||
packetsReceivedTotal *prometheus.Desc
|
||||
releasesTotal *prometheus.Desc
|
||||
requestsTotal *prometheus.Desc
|
||||
|
||||
scopeInfo *prometheus.Desc
|
||||
scopeState *prometheus.Desc
|
||||
scopeAddressesFreeTotal *prometheus.Desc
|
||||
scopeAddressesFreeOnPartnerServerTotal *prometheus.Desc
|
||||
scopeAddressesFreeOnThisServerTotal *prometheus.Desc
|
||||
scopeAddressesInUseTotal *prometheus.Desc
|
||||
scopeAddressesInUseOnPartnerServerTotal *prometheus.Desc
|
||||
scopeAddressesInUseOnThisServerTotal *prometheus.Desc
|
||||
scopePendingOffersTotal *prometheus.Desc
|
||||
scopeReservedAddressTotal *prometheus.Desc
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
@@ -72,6 +100,10 @@ func New(config *Config) *Collector {
|
||||
config = &ConfigDefaults
|
||||
}
|
||||
|
||||
if config.CollectorsEnabled == nil {
|
||||
config.CollectorsEnabled = ConfigDefaults.CollectorsEnabled
|
||||
}
|
||||
|
||||
c := &Collector{
|
||||
config: *config,
|
||||
}
|
||||
@@ -79,8 +111,26 @@ func New(config *Config) *Collector {
|
||||
return c
|
||||
}
|
||||
|
||||
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||
return &Collector{}
|
||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
||||
c := &Collector{
|
||||
config: ConfigDefaults,
|
||||
}
|
||||
c.config.CollectorsEnabled = make([]string, 0)
|
||||
|
||||
var collectorsEnabled string
|
||||
|
||||
app.Flag(
|
||||
"collector.dhcp.enabled",
|
||||
"Comma-separated list of collectors to use. Defaults to all, if not specified.",
|
||||
).Default(strings.Join(ConfigDefaults.CollectorsEnabled, ",")).StringVar(&collectorsEnabled)
|
||||
|
||||
app.Action(func(*kingpin.ParseContext) error {
|
||||
c.config.CollectorsEnabled = strings.Split(collectorsEnabled, ",")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Collector) GetName() string {
|
||||
@@ -88,7 +138,9 @@ func (c *Collector) GetName() string {
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
c.perfDataCollector.Close()
|
||||
if slices.Contains(c.config.CollectorsEnabled, subCollectorServerMetrics) {
|
||||
c.perfDataCollector.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -96,166 +148,258 @@ func (c *Collector) Close() error {
|
||||
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DHCP Server", nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DHCP Server collector: %w", err)
|
||||
if slices.Contains(c.config.CollectorsEnabled, subCollectorServerMetrics) {
|
||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](pdh.CounterTypeRaw, "DHCP Server", nil)
|
||||
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)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.duplicatesDroppedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "duplicates_dropped_total"),
|
||||
"Total number of duplicate packets received by the DHCP server (DuplicatesDroppedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.packetsExpiredTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "packets_expired_total"),
|
||||
"Total number of packets expired in the DHCP server message queue (PacketsExpiredTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.activeQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "active_queue_length"),
|
||||
"Number of packets in the processing queue of the DHCP server (ActiveQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.conflictCheckQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "conflict_check_queue_length"),
|
||||
"Number of packets in the DHCP server queue waiting on conflict detection (ping). (ConflictCheckQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.discoversTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "discovers_total"),
|
||||
"Total DHCP Discovers received by the DHCP server (DiscoversTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.offersTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "offers_total"),
|
||||
"Total DHCP Offers sent by the DHCP server (OffersTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.requestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
|
||||
"Total DHCP Requests received by the DHCP server (RequestsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.informsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "informs_total"),
|
||||
"Total DHCP Informs received by the DHCP server (InformsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.acksTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "acks_total"),
|
||||
"Total DHCP Acks sent by the DHCP server (AcksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.nACKsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "nacks_total"),
|
||||
"Total DHCP Nacks sent by the DHCP server (NacksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.declinesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "declines_total"),
|
||||
"Total DHCP Declines received by the DHCP server (DeclinesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.releasesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "releases_total"),
|
||||
"Total DHCP Releases received by the DHCP server (ReleasesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.offerQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "offer_queue_length"),
|
||||
"Number of packets in the offer queue of the DHCP server (OfferQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.deniedDueToMatch = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "denied_due_to_match_total"),
|
||||
"Total number of DHCP requests denied, based on matches from the Deny list (DeniedDueToMatch)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.deniedDueToNonMatch = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "denied_due_to_nonmatch_total"),
|
||||
"Total number of DHCP requests denied, based on non-matches from the Allow list (DeniedDueToNonMatch)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_pending_in_outbound_queue"),
|
||||
"Number of pending outbound DHCP fail over Binding Update messages (FailoverBndupdPendingOutboundQueue)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverTransitionsCommunicationInterruptedState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_communicationinterrupted_state_total"),
|
||||
"Total number of transitions into COMMUNICATION INTERRUPTED state (FailoverTransitionsCommunicationinterruptedState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverTransitionsPartnerDownState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_partnerdown_state_total"),
|
||||
"Total number of transitions into PARTNER DOWN state (FailoverTransitionsPartnerdownState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverTransitionsRecoverState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_recover_total"),
|
||||
"Total number of transitions into RECOVER state (FailoverTransitionsRecoverState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndUpdDropped = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_dropped_total"),
|
||||
"Total number of DHCP fail over Binding Updates dropped (FailoverBndupdDropped)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
c.packetsReceivedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "packets_received_total"),
|
||||
"Total number of packets received by the DHCP server (PacketsReceivedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.duplicatesDroppedTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "duplicates_dropped_total"),
|
||||
"Total number of duplicate packets received by the DHCP server (DuplicatesDroppedTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.packetsExpiredTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "packets_expired_total"),
|
||||
"Total number of packets expired in the DHCP server message queue (PacketsExpiredTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.activeQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "active_queue_length"),
|
||||
"Number of packets in the processing queue of the DHCP server (ActiveQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.conflictCheckQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "conflict_check_queue_length"),
|
||||
"Number of packets in the DHCP server queue waiting on conflict detection (ping). (ConflictCheckQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.discoversTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "discovers_total"),
|
||||
"Total DHCP Discovers received by the DHCP server (DiscoversTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.offersTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "offers_total"),
|
||||
"Total DHCP Offers sent by the DHCP server (OffersTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.requestsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
|
||||
"Total DHCP Requests received by the DHCP server (RequestsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.informsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "informs_total"),
|
||||
"Total DHCP Informs received by the DHCP server (InformsTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.acksTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "acks_total"),
|
||||
"Total DHCP Acks sent by the DHCP server (AcksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.nACKsTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "nacks_total"),
|
||||
"Total DHCP Nacks sent by the DHCP server (NacksTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.declinesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "declines_total"),
|
||||
"Total DHCP Declines received by the DHCP server (DeclinesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.releasesTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "releases_total"),
|
||||
"Total DHCP Releases received by the DHCP server (ReleasesTotal)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.offerQueueLength = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "offer_queue_length"),
|
||||
"Number of packets in the offer queue of the DHCP server (OfferQueueLength)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.deniedDueToMatch = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "denied_due_to_match_total"),
|
||||
"Total number of DHCP requests denied, based on matches from the Deny list (DeniedDueToMatch)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.deniedDueToNonMatch = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "denied_due_to_nonmatch_total"),
|
||||
"Total number of DHCP requests denied, based on non-matches from the Allow list (DeniedDueToNonMatch)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_pending_in_outbound_queue"),
|
||||
"Number of pending outbound DHCP fail over Binding Update messages (FailoverBndupdPendingOutboundQueue)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverTransitionsCommunicationInterruptedState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_communicationinterrupted_state_total"),
|
||||
"Total number of transitions into COMMUNICATION INTERRUPTED state (FailoverTransitionsCommunicationinterruptedState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverTransitionsPartnerDownState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_partnerdown_state_total"),
|
||||
"Total number of transitions into PARTNER DOWN state (FailoverTransitionsPartnerdownState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverTransitionsRecoverState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_transitions_recover_total"),
|
||||
"Total number of transitions into RECOVER state (FailoverTransitionsRecoverState)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.failoverBndUpdDropped = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "failover_bndupd_dropped_total"),
|
||||
"Total number of DHCP fail over Binding Updates dropped (FailoverBndupdDropped)",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
if slices.Contains(c.config.CollectorsEnabled, subCollectorScopeMetrics) {
|
||||
c.scopeInfo = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_info"),
|
||||
"DHCP Scope information",
|
||||
[]string{"name", "superscope_name", "superscope_id", "scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeState = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_state"),
|
||||
"DHCP Scope state",
|
||||
[]string{"scope", "state"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeAddressesFreeTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_addresses_free"),
|
||||
"DHCP Scope free addresses",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeAddressesFreeOnPartnerServerTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_addresses_free_on_partner_server"),
|
||||
"DHCP Scope free addresses on partner server",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeAddressesFreeOnThisServerTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_addresses_free_on_this_server"),
|
||||
"DHCP Scope free addresses on this server",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeAddressesInUseTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_addresses_in_use"),
|
||||
"DHCP Scope addresses in use",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeAddressesInUseOnPartnerServerTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_addresses_in_use_on_partner_server"),
|
||||
"DHCP Scope addresses in use on partner server",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeAddressesInUseOnThisServerTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_addresses_in_use_on_this_server"),
|
||||
"DHCP Scope addresses in use on this server",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopePendingOffersTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_pending_offers"),
|
||||
"DHCP Scope pending offers",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.scopeReservedAddressTotal = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "scope_reserved_address"),
|
||||
"DHCP Scope reserved addresses",
|
||||
[]string{"scope"},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
var errs []error
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, subCollectorServerMetrics) {
|
||||
if err := c.collectServerMetrics(ch); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(c.config.CollectorsEnabled, subCollectorScopeMetrics) {
|
||||
if err := c.collectScopeMetrics(ch); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (c *Collector) collectServerMetrics(ch chan<- prometheus.Metric) error {
|
||||
err := c.perfDataCollector.Collect(&c.perfDataObject)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to collect DHCP Server metrics: %w", err)
|
||||
@@ -413,3 +557,113 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectScopeMetrics(ch chan<- prometheus.Metric) error {
|
||||
dhcpScopes, err := dhcpsapi.GetDHCPV4ScopeStatistics()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get DHCP scopes: %w", err)
|
||||
}
|
||||
|
||||
for _, scope := range dhcpScopes {
|
||||
scopeID := scope.ScopeIPAddress.String()
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeInfo,
|
||||
prometheus.GaugeValue,
|
||||
1,
|
||||
scope.Name,
|
||||
scope.SuperScopeName,
|
||||
strconv.Itoa(int(scope.SuperScopeNumber)),
|
||||
scopeID,
|
||||
)
|
||||
|
||||
for state, name := range dhcpsapi.DHCP_SUBNET_STATE_NAMES {
|
||||
metric := 0.0
|
||||
if state == scope.State {
|
||||
metric = 1.0
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeState,
|
||||
prometheus.GaugeValue,
|
||||
metric,
|
||||
scopeID,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.AddressesFree != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeAddressesFreeTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.AddressesFree,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.AddressesFreeOnPartnerServer != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeAddressesFreeOnPartnerServerTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.AddressesFreeOnPartnerServer,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.AddressesFreeOnThisServer != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeAddressesFreeOnThisServerTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.AddressesFreeOnThisServer,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.AddressesInUse != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeAddressesInUseTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.AddressesInUse,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.AddressesInUseOnPartnerServer != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeAddressesInUseOnPartnerServerTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.AddressesInUseOnPartnerServer,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.AddressesInUseOnThisServer != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeAddressesInUseOnThisServerTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.AddressesInUseOnThisServer,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.PendingOffers != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopePendingOffersTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.PendingOffers,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
|
||||
if scope.ReservedAddress != -1 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.scopeReservedAddressTotal,
|
||||
prometheus.GaugeValue,
|
||||
scope.ReservedAddress,
|
||||
scopeID,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -23,11 +23,10 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -157,19 +156,17 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
version := windows.RtlGetVersion()
|
||||
|
||||
subCollectors := map[string]struct {
|
||||
build func() error
|
||||
collect func(ch chan<- prometheus.Metric) error
|
||||
close func()
|
||||
minBuildNumber uint32
|
||||
minBuildNumber uint16
|
||||
}{
|
||||
subCollectorDataStore: {
|
||||
build: c.buildDataStore,
|
||||
collect: c.collectDataStore,
|
||||
close: c.perfDataCollectorDataStore.Close,
|
||||
minBuildNumber: types.BuildNumberWindowsServer2022,
|
||||
minBuildNumber: osversion.LTSC2022,
|
||||
},
|
||||
subCollectorDynamicMemoryBalancer: {
|
||||
build: c.buildDynamicMemoryBalancer,
|
||||
@@ -243,6 +240,8 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
},
|
||||
}
|
||||
|
||||
buildNumber := osversion.Build()
|
||||
|
||||
// Result must order, to prevent test failures.
|
||||
sort.Strings(c.config.CollectorsEnabled)
|
||||
|
||||
@@ -253,7 +252,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||
return fmt.Errorf("unknown collector: %s", name)
|
||||
}
|
||||
|
||||
if version.BuildNumber < subCollectors[name].minBuildNumber {
|
||||
if buildNumber < subCollectors[name].minBuildNumber {
|
||||
errs = append(errs, fmt.Errorf("collector %s requires Windows Server 2022 or newer", name))
|
||||
|
||||
continue
|
||||
|
||||
@@ -18,6 +18,7 @@ package mscluster
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -192,7 +193,14 @@ type msClusterCluster struct {
|
||||
}
|
||||
|
||||
func (c *Collector) buildCluster() error {
|
||||
clusterMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Cluster")
|
||||
buildNumber := osversion.Build()
|
||||
|
||||
wmiSelect := "AddEvictDelay,AdminAccessPoint,AutoAssignNodeSite,AutoBalancerLevel,AutoBalancerMode,BackupInProgress,BlockCacheSize,ClusSvcHangTimeout,ClusSvcRegroupOpeningTimeout,ClusSvcRegroupPruningTimeout,ClusSvcRegroupStageTimeout,ClusSvcRegroupTickInMilliseconds,ClusterEnforcedAntiAffinity,ClusterFunctionalLevel,ClusterGroupWaitDelay,ClusterLogLevel,ClusterLogSize,ClusterUpgradeVersion,CrossSiteDelay,CrossSiteThreshold,CrossSubnetDelay,CrossSubnetThreshold,CsvBalancer,DatabaseReadWriteMode,DefaultNetworkRole,DisableGroupPreferredOwnerRandomization,DrainOnShutdown,DynamicQuorumEnabled,EnableSharedVolumes,FixQuorum,GracePeriodEnabled,GracePeriodTimeout,GroupDependencyTimeout,HangRecoveryAction,IgnorePersistentStateOnStartup,LogResourceControls,LowerQuorumPriorityNodeId,MessageBufferLength,MinimumNeverPreemptPriority,MinimumPreemptorPriority,NetftIPSecEnabled,PlacementOptions,PlumbAllCrossSubnetRoutes,PreventQuorum,QuarantineDuration,QuarantineThreshold,QuorumArbitrationTimeMax,QuorumArbitrationTimeMin,QuorumLogFileSize,QuorumTypeValue,RequestReplyTimeout,ResiliencyDefaultPeriod,ResiliencyLevel,ResourceDllDeadlockPeriod,RootMemoryReserved,RouteHistoryLength,S2DBusTypes,S2DCacheDesiredState,S2DCacheFlashReservePercent,S2DCachePageSizeKBytes,S2DEnabled,S2DIOLatencyThreshold,S2DOptimizations,SameSubnetDelay,SameSubnetThreshold,SecurityLevel,SharedVolumeVssWriterOperationTimeout,ShutdownTimeoutInMinutes,UseClientAccessNetworksForSharedVolumes,WitnessDatabaseWriteTimeout,WitnessDynamicWeight,WitnessRestartInterval"
|
||||
if buildNumber >= osversion.LTSC2022 {
|
||||
wmiSelect += ",DetectManagedEvents,SecurityLevelForStorage,MaxNumberOfNodes,DetectManagedEventsThreshold,DetectedCloudPlatform"
|
||||
}
|
||||
|
||||
clusterMIQuery, err := mi.NewQuery(fmt.Sprintf("SELECT %s FROM MSCluster_Cluster", wmiSelect))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
@@ -852,27 +860,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterDetectedCloudPlatform,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectedCloudPlatform),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterDetectManagedEvents,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectManagedEvents),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterDetectManagedEventsThreshold,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectManagedEventsThreshold),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterDisableGroupPreferredOwnerRandomization,
|
||||
prometheus.GaugeValue,
|
||||
@@ -957,13 +944,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterMaxNumberOfNodes,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MaxNumberOfNodes),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterMessageBufferLength,
|
||||
prometheus.GaugeValue,
|
||||
@@ -1167,13 +1147,6 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterSecurityLevelForStorage,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.SecurityLevelForStorage),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterSharedVolumeVssWriterOperationTimeout,
|
||||
prometheus.GaugeValue,
|
||||
@@ -1215,6 +1188,43 @@ func (c *Collector) collectCluster(ch chan<- prometheus.Metric) error {
|
||||
float64(v.WitnessRestartInterval),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
if osversion.Build() >= osversion.LTSC2022 {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterDetectManagedEvents,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectManagedEvents),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterDetectManagedEventsThreshold,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectManagedEventsThreshold),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterSecurityLevelForStorage,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.SecurityLevelForStorage),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterMaxNumberOfNodes,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.MaxNumberOfNodes),
|
||||
v.Name,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.clusterDetectedCloudPlatform,
|
||||
prometheus.GaugeValue,
|
||||
float64(v.DetectedCloudPlatform),
|
||||
v.Name,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -48,7 +48,7 @@ type msClusterNetwork struct {
|
||||
}
|
||||
|
||||
func (c *Collector) buildNetwork() error {
|
||||
networkMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Network")
|
||||
networkMIQuery, err := mi.NewQuery("SELECT Characteristics,Flags,Metric,Role,State FROM MSCluster_Network")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package mscluster
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -66,7 +67,14 @@ type msClusterNode struct {
|
||||
}
|
||||
|
||||
func (c *Collector) buildNode() error {
|
||||
nodeMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Node")
|
||||
buildNumber := osversion.Build()
|
||||
|
||||
wmiSelect := "BuildNumber,Characteristics,DynamicWeight,Flags,MajorVersion,MinorVersion,NeedsPreventQuorum,NodeDrainStatus,NodeHighestVersion,NodeLowestVersion,NodeWeight,State,StatusInformation"
|
||||
if buildNumber >= osversion.LTSC2022 {
|
||||
wmiSelect += ",DetectedCloudPlatform"
|
||||
}
|
||||
|
||||
nodeMIQuery, err := mi.NewQuery(fmt.Sprintf("SELECT %s FROM MSCluster_Node", wmiSelect))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ type msClusterResource struct {
|
||||
}
|
||||
|
||||
func (c *Collector) buildResource() error {
|
||||
resourceMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_Resource")
|
||||
resourceMIQuery, err := mi.NewQuery("SELECT Name,Type,OwnerGroup,OwnerNode,Characteristics,DeadlockTimeout,EmbeddedFailureAction,Flags,IsAlivePollInterval,LooksAlivePollInterval,MonitorProcessId,PendingTimeout,ResourceClass,RestartAction,RestartDelay,RestartPeriod,RestartThreshold,RetryPeriodOnFailure,State,Subclass FROM MSCluster_Resource")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ type msClusterResourceGroup struct {
|
||||
}
|
||||
|
||||
func (c *Collector) buildResourceGroup() error {
|
||||
resourceGroupMIQuery, err := mi.NewQuery("SELECT * FROM MSCluster_ResourceGroup")
|
||||
resourceGroupMIQuery, err := mi.NewQuery("SELECT AutoFailbackType,Characteristics,ColdStartSetting,DefaultOwner,FailbackWindowEnd,FailbackWindowStart,FailoverPeriod,FailoverThreshold,Flags,GroupType,OwnerNode,Priority,ResiliencyPeriod,State FROM MSCluster_ResourceGroup")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ type Win32_PerfRawData_NETFramework_NETCLRExceptions struct {
|
||||
|
||||
func (c *Collector) collectClrExceptions(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRExceptions
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRExceptions"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRExceptions"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ type Win32_PerfRawData_NETFramework_NETCLRInterop struct {
|
||||
|
||||
func (c *Collector) collectClrInterop(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRInterop
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRInterop"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRInterop"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ type Win32_PerfRawData_NETFramework_NETCLRJit struct {
|
||||
|
||||
func (c *Collector) collectClrJIT(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRJit
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRJit"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRJit"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ type Win32_PerfRawData_NETFramework_NETCLRLoading struct {
|
||||
|
||||
func (c *Collector) collectClrLoading(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLoading
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRLoading"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRLoading"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ type Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads struct {
|
||||
|
||||
func (c *Collector) collectClrLocksAndThreads(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ type Win32_PerfRawData_NETFramework_NETCLRMemory struct {
|
||||
|
||||
func (c *Collector) collectClrMemory(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRMemory
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRMemory"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRMemory"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ type Win32_PerfRawData_NETFramework_NETCLRRemoting struct {
|
||||
|
||||
func (c *Collector) collectClrRemoting(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRRemoting
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRRemoting"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRRemoting"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ type Win32_PerfRawData_NETFramework_NETCLRSecurity struct {
|
||||
|
||||
func (c *Collector) collectClrSecurity(ch chan<- prometheus.Metric) error {
|
||||
var dst []Win32_PerfRawData_NETFramework_NETCLRSecurity
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * Win32_PerfRawData_NETFramework_NETCLRSecurity"))); err != nil {
|
||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, utils.Must(mi.NewQuery("SELECT * FROM Win32_PerfRawData_NETFramework_NETCLRSecurity"))); err != nil {
|
||||
return fmt.Errorf("WMI query failed: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,5 +28,7 @@ func BenchmarkCollector(b *testing.B) {
|
||||
}
|
||||
|
||||
func TestCollector(t *testing.T) {
|
||||
t.Skip("Skipping test as it requires WMI data")
|
||||
|
||||
testutils.TestCollector(t, netframework.New, nil)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ type Collector struct {
|
||||
poolBytes *prometheus.Desc
|
||||
priorityBase *prometheus.Desc
|
||||
privateBytes *prometheus.Desc
|
||||
// Deprecated: Use start_time_seconds_timestamp instead
|
||||
startTimeOld *prometheus.Desc
|
||||
startTime *prometheus.Desc
|
||||
threadCount *prometheus.Desc
|
||||
virtualBytes *prometheus.Desc
|
||||
@@ -214,8 +216,15 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
||||
nil,
|
||||
)
|
||||
|
||||
c.startTime = prometheus.NewDesc(
|
||||
c.startTimeOld = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "start_time"),
|
||||
"DEPRECATED: Use start_time_seconds_timestamp instead",
|
||||
[]string{"process", "process_id"},
|
||||
nil,
|
||||
)
|
||||
|
||||
c.startTime = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "start_time_seconds_timestamp"),
|
||||
"Time of process start.",
|
||||
[]string{"process", "process_id"},
|
||||
nil,
|
||||
|
||||
@@ -141,6 +141,13 @@ func (c *Collector) collectWorkerV1() {
|
||||
name, pidString,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.startTimeOld,
|
||||
prometheus.GaugeValue,
|
||||
data.ElapsedTime,
|
||||
name, pidString,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.handleCount,
|
||||
prometheus.GaugeValue,
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@@ -134,10 +135,19 @@ func (c *Collector) collectWorkerV2() {
|
||||
name, pidString, parentPID, strconv.Itoa(int(processGroupID)), processOwner, cmdLine,
|
||||
)
|
||||
|
||||
startTime := float64(time.Now().Unix() - int64(data.ElapsedTime))
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.startTimeOld,
|
||||
prometheus.GaugeValue,
|
||||
startTime,
|
||||
name, pidString,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.startTime,
|
||||
prometheus.GaugeValue,
|
||||
data.ElapsedTime,
|
||||
startTime,
|
||||
name, pidString,
|
||||
)
|
||||
|
||||
|
||||
@@ -64,7 +64,8 @@ type Collector struct {
|
||||
// ref: https://victoriametrics.com/blog/go-sync-pool/
|
||||
serviceConfigPoolBytes sync.Pool
|
||||
|
||||
serviceManagerHandle *mgr.Mgr
|
||||
serviceManagerHandle *mgr.Mgr
|
||||
queryAllServicesBuffer []byte
|
||||
}
|
||||
|
||||
func New(config *Config) *Collector {
|
||||
@@ -140,6 +141,8 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||
},
|
||||
}
|
||||
|
||||
c.queryAllServicesBuffer = make([]byte, 1024*100)
|
||||
|
||||
c.info = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||
"A metric with a constant '1' value labeled with service information",
|
||||
@@ -209,7 +212,7 @@ func (c *Collector) Close() error {
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||
services, err := c.queryAllServices()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query services: %w", err)
|
||||
return fmt.Errorf("failed to query all services: %w", err)
|
||||
}
|
||||
|
||||
servicesCh := make(chan windows.ENUM_SERVICE_STATUS_PROCESS, len(services))
|
||||
@@ -368,16 +371,16 @@ func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, e
|
||||
err error
|
||||
)
|
||||
|
||||
buf := make([]byte, 1024*100)
|
||||
|
||||
for {
|
||||
currentBufferSize := uint32(cap(c.queryAllServicesBuffer))
|
||||
|
||||
err = windows.EnumServicesStatusEx(
|
||||
c.serviceManagerHandle.Handle,
|
||||
windows.SC_STATUS_PROCESS_INFO,
|
||||
windows.SERVICE_WIN32,
|
||||
windows.SERVICE_STATE_ALL,
|
||||
&buf[0],
|
||||
uint32(len(buf)),
|
||||
&c.queryAllServicesBuffer[0],
|
||||
currentBufferSize,
|
||||
&bytesNeeded,
|
||||
&servicesReturned,
|
||||
nil,
|
||||
@@ -392,18 +395,18 @@ func (c *Collector) queryAllServices() ([]windows.ENUM_SERVICE_STATUS_PROCESS, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if bytesNeeded <= uint32(len(buf)) {
|
||||
return nil, err
|
||||
if bytesNeeded <= currentBufferSize {
|
||||
return nil, fmt.Errorf("windows.EnumServicesStatusEx reports buffer too small (%d), but buffer is large enough (%d)", currentBufferSize, bytesNeeded)
|
||||
}
|
||||
|
||||
buf = make([]byte, bytesNeeded)
|
||||
c.queryAllServicesBuffer = make([]byte, bytesNeeded)
|
||||
}
|
||||
|
||||
if servicesReturned == 0 {
|
||||
return []windows.ENUM_SERVICE_STATUS_PROCESS{}, nil
|
||||
}
|
||||
|
||||
services := unsafe.Slice((*windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0])), int(servicesReturned))
|
||||
services := unsafe.Slice((*windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&c.queryAllServicesBuffer[0])), int(servicesReturned))
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
@@ -42,10 +42,14 @@ type Resolver struct {
|
||||
func NewResolver(ctx context.Context, file string, logger *slog.Logger, insecureSkipVerify bool) (*Resolver, error) {
|
||||
flags := map[string]string{}
|
||||
|
||||
var fileBytes []byte
|
||||
var (
|
||||
err error
|
||||
fileBytes []byte
|
||||
)
|
||||
|
||||
var err error
|
||||
if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") {
|
||||
logger.WarnContext(ctx, "Loading configuration file from URL is deprecated and will be removed in 0.31.0. Use a local file instead.")
|
||||
|
||||
fileBytes, err = readFromURL(ctx, file, logger, insecureSkipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
214
internal/headers/dhcpsapi/dhcpsapi.go
Normal file
214
internal/headers/dhcpsapi/dhcpsapi.go
Normal file
@@ -0,0 +1,214 @@
|
||||
package dhcpsapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var (
|
||||
modDhcpServer = windows.NewLazySystemDLL("dhcpsapi.dll")
|
||||
procDhcpGetSubnetInfo = modDhcpServer.NewProc("DhcpGetSubnetInfo")
|
||||
procDhcpGetSuperScopeInfoV4 = modDhcpServer.NewProc("DhcpGetSuperScopeInfoV4")
|
||||
procDhcpRpcFreeMemory = modDhcpServer.NewProc("DhcpRpcFreeMemory")
|
||||
procDhcpV4EnumSubnetReservations = modDhcpServer.NewProc("DhcpV4EnumSubnetReservations")
|
||||
procDhcpV4FailoverGetScopeStatistics = modDhcpServer.NewProc("DhcpV4FailoverGetScopeStatistics")
|
||||
procDhcpGetMibInfoV5 = modDhcpServer.NewProc("DhcpGetMibInfoV5")
|
||||
)
|
||||
|
||||
func GetDHCPV4ScopeStatistics() ([]DHCPV4Scope, error) {
|
||||
var mibInfo *DHCP_MIB_INFO_V5
|
||||
|
||||
if err := dhcpGetMibInfoV5(&mibInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer dhcpRpcFreeMemory(unsafe.Pointer(mibInfo))
|
||||
|
||||
subnetScopeInfos := make(map[DHCP_IP_ADDRESS]DHCP_SUBNET_MIB_INFO_V5, mibInfo.Scopes)
|
||||
subnetMIBScopeInfos := unsafe.Slice(mibInfo.ScopeInfo, mibInfo.Scopes)
|
||||
|
||||
for _, subnetMIBScopeInfo := range subnetMIBScopeInfos {
|
||||
subnetScopeInfos[subnetMIBScopeInfo.Subnet] = subnetMIBScopeInfo
|
||||
}
|
||||
|
||||
var superScopeTable *DHCP_SUPER_SCOPE_TABLE
|
||||
|
||||
if err := dhcpGetSuperScopeInfoV4(&superScopeTable); err != nil {
|
||||
return nil, err
|
||||
} else if superScopeTable == nil {
|
||||
return nil, errors.New("dhcpGetSuperScopeInfoV4 returned nil")
|
||||
}
|
||||
|
||||
defer dhcpRpcFreeMemory(unsafe.Pointer(superScopeTable))
|
||||
|
||||
scopes := make([]DHCPV4Scope, 0, superScopeTable.Count)
|
||||
subnets := unsafe.Slice(superScopeTable.Entries, superScopeTable.Count)
|
||||
|
||||
var errs []error
|
||||
|
||||
for _, subnet := range subnets {
|
||||
if err := (func() error {
|
||||
var subnetInfo *DHCP_SUBNET_INFO
|
||||
err := dhcpGetSubnetInfo(subnet.SubnetAddress, &subnetInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get subnet info: %w", err)
|
||||
}
|
||||
|
||||
defer dhcpRpcFreeMemory(unsafe.Pointer(subnetInfo))
|
||||
|
||||
scope := DHCPV4Scope{
|
||||
Name: subnetInfo.SubnetName.String(),
|
||||
SuperScopeName: subnet.SuperScopeName.String(),
|
||||
ScopeIPAddress: net.IPNet{IP: subnetInfo.SubnetAddress.IPv4(), Mask: subnetInfo.SubnetMask.IPv4Mask()},
|
||||
SuperScopeNumber: subnet.SuperScopeNumber,
|
||||
State: subnetInfo.SubnetState,
|
||||
|
||||
AddressesFree: -1,
|
||||
AddressesFreeOnPartnerServer: -1,
|
||||
AddressesFreeOnThisServer: -1,
|
||||
AddressesInUse: -1,
|
||||
AddressesInUseOnPartnerServer: -1,
|
||||
AddressesInUseOnThisServer: -1,
|
||||
PendingOffers: -1,
|
||||
ReservedAddress: -1,
|
||||
}
|
||||
|
||||
if subnetScopeInfo, ok := subnetScopeInfos[subnetInfo.SubnetAddress]; ok {
|
||||
scope.AddressesInUse = float64(subnetScopeInfo.NumAddressesInUse)
|
||||
scope.AddressesFree = float64(subnetScopeInfo.NumAddressesFree)
|
||||
scope.PendingOffers = float64(subnetScopeInfo.NumPendingOffers)
|
||||
}
|
||||
|
||||
subnetReservationCount, err := dhcpV4EnumSubnetReservations(subnet.SubnetAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get subnet reservation count: %w", err)
|
||||
} else {
|
||||
scope.ReservedAddress = float64(subnetReservationCount)
|
||||
}
|
||||
|
||||
var subnetStatistics *DHCP_FAILOVER_STATISTICS
|
||||
err = dhcpV4FailoverGetScopeStatistics(subnet.SubnetAddress, &subnetStatistics)
|
||||
|
||||
defer dhcpRpcFreeMemory(unsafe.Pointer(subnetStatistics))
|
||||
|
||||
if err == nil {
|
||||
scope.AddressesFree = float64(subnetStatistics.AddrFree)
|
||||
scope.AddressesInUse = float64(subnetStatistics.AddrInUse)
|
||||
scope.AddressesFreeOnPartnerServer = float64(subnetStatistics.PartnerAddrFree)
|
||||
scope.AddressesInUseOnPartnerServer = float64(subnetStatistics.PartnerAddrInUse)
|
||||
scope.AddressesFreeOnThisServer = float64(subnetStatistics.ThisAddrFree)
|
||||
scope.AddressesInUseOnThisServer = float64(subnetStatistics.ThisAddrInUse)
|
||||
} else if !errors.Is(err, ERROR_DHCP_FO_SCOPE_NOT_IN_RELATIONSHIP) {
|
||||
return fmt.Errorf("failed to get subnet statistics: %w", err)
|
||||
}
|
||||
|
||||
scopes = append(scopes, scope)
|
||||
|
||||
return nil
|
||||
})(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
return scopes, errors.Join(errs...)
|
||||
}
|
||||
|
||||
// dhcpGetSubnetInfo https://learn.microsoft.com/en-us/windows/win32/api/dhcpsapi/nf-dhcpsapi-dhcpgetsubnetinfo
|
||||
func dhcpGetSubnetInfo(subnetAddress DHCP_IP_ADDRESS, subnetInfo **DHCP_SUBNET_INFO) error {
|
||||
ret, _, _ := procDhcpGetSubnetInfo.Call(
|
||||
0,
|
||||
uintptr(subnetAddress),
|
||||
uintptr(unsafe.Pointer(subnetInfo)),
|
||||
)
|
||||
|
||||
if ret != 0 {
|
||||
return fmt.Errorf("dhcpGetSubnetInfo failed with code %w", windows.Errno(ret))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dhcpV4FailoverGetScopeStatistics https://learn.microsoft.com/en-us/windows/win32/api/dhcpsapi/nf-dhcpsapi-dhcpv4failovergetscopestatistics
|
||||
func dhcpV4FailoverGetScopeStatistics(scopeId DHCP_IP_ADDRESS, stats **DHCP_FAILOVER_STATISTICS) error {
|
||||
ret, _, _ := procDhcpV4FailoverGetScopeStatistics.Call(
|
||||
0,
|
||||
uintptr(scopeId),
|
||||
uintptr(unsafe.Pointer(stats)),
|
||||
)
|
||||
|
||||
if ret != 0 {
|
||||
return fmt.Errorf("dhcpV4FailoverGetScopeStatistics failed with code %w", windows.Errno(ret))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dhcpGetSuperScopeInfoV4 https://learn.microsoft.com/en-us/windows/win32/api/dhcpsapi/nf-dhcpsapi-dhcpgetsuperscopeinfov4
|
||||
func dhcpGetSuperScopeInfoV4(superScopeTable **DHCP_SUPER_SCOPE_TABLE) error {
|
||||
ret, _, _ := procDhcpGetSuperScopeInfoV4.Call(
|
||||
0,
|
||||
uintptr(unsafe.Pointer(superScopeTable)),
|
||||
)
|
||||
|
||||
if ret != 0 {
|
||||
return fmt.Errorf("dhcpGetSuperScopeInfoV4 failed with code %w", windows.Errno(ret))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dhcpGetMibInfoV5 https://learn.microsoft.com/en-us/windows/win32/api/dhcpsapi/nf-dhcpsapi-dhcpgetmibinfov5
|
||||
func dhcpGetMibInfoV5(mibInfo **DHCP_MIB_INFO_V5) error {
|
||||
ret, _, _ := procDhcpGetMibInfoV5.Call(
|
||||
0,
|
||||
uintptr(unsafe.Pointer(mibInfo)),
|
||||
)
|
||||
|
||||
if ret != 0 {
|
||||
return fmt.Errorf("dhcpGetMibInfoV5 failed with code %w", windows.Errno(ret))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dhcpV4EnumSubnetReservations https://learn.microsoft.com/en-us/windows/win32/api/dhcpsapi/nf-dhcpsapi-dhcpv4enumsubnetreservations
|
||||
func dhcpV4EnumSubnetReservations(subnetAddress DHCP_IP_ADDRESS) (uint32, error) {
|
||||
var (
|
||||
elementsRead uint32
|
||||
elementsTotal uint32
|
||||
elementsInfo uintptr
|
||||
resumeHandle *windows.Handle
|
||||
)
|
||||
|
||||
ret, _, _ := procDhcpV4EnumSubnetReservations.Call(
|
||||
0,
|
||||
uintptr(subnetAddress),
|
||||
uintptr(unsafe.Pointer(&resumeHandle)),
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&elementsInfo)),
|
||||
uintptr(unsafe.Pointer(&elementsRead)),
|
||||
uintptr(unsafe.Pointer(&elementsTotal)),
|
||||
)
|
||||
|
||||
dhcpRpcFreeMemory(unsafe.Pointer(elementsInfo))
|
||||
|
||||
if !errors.Is(windows.Errno(ret), windows.ERROR_MORE_DATA) && !errors.Is(windows.Errno(ret), windows.ERROR_NO_MORE_ITEMS) {
|
||||
return 0, fmt.Errorf("dhcpV4EnumSubnetReservations failed with code %w", windows.Errno(ret))
|
||||
}
|
||||
|
||||
return elementsRead + elementsTotal, nil
|
||||
}
|
||||
|
||||
func dhcpRpcFreeMemory(pointer unsafe.Pointer) {
|
||||
if uintptr(pointer) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
//nolint:dogsled
|
||||
_, _, _ = procDhcpRpcFreeMemory.Call(uintptr(pointer))
|
||||
}
|
||||
24
internal/headers/dhcpsapi/dhcpsapi_test.go
Normal file
24
internal/headers/dhcpsapi/dhcpsapi_test.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package dhcpsapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func TestGetDHCPV4ScopeStatistics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if procDhcpGetSuperScopeInfoV4.Find() != nil {
|
||||
t.Skip("DhcpGetSuperScopeInfoV4 is not available")
|
||||
}
|
||||
|
||||
_, err := GetDHCPV4ScopeStatistics()
|
||||
if errors.Is(err, windows.Errno(1753)) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
}
|
||||
137
internal/headers/dhcpsapi/types.go
Normal file
137
internal/headers/dhcpsapi/types.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package dhcpsapi
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/headers/win32api"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var ERROR_DHCP_FO_SCOPE_NOT_IN_RELATIONSHIP = windows.Errno(20116)
|
||||
|
||||
type DHCPV4Scope struct {
|
||||
Name string
|
||||
State DHCP_SUBNET_STATE
|
||||
SuperScopeName string
|
||||
SuperScopeNumber uint32
|
||||
ScopeIPAddress net.IPNet
|
||||
|
||||
AddressesFree float64
|
||||
AddressesFreeOnPartnerServer float64
|
||||
AddressesFreeOnThisServer float64
|
||||
AddressesInUse float64
|
||||
AddressesInUseOnPartnerServer float64
|
||||
AddressesInUseOnThisServer float64
|
||||
PendingOffers float64
|
||||
ReservedAddress float64
|
||||
}
|
||||
|
||||
type (
|
||||
DHCP_IP_ADDRESS win32api.DWORD
|
||||
DHCP_IP_MASK win32api.DWORD
|
||||
)
|
||||
|
||||
func (ip DHCP_IP_ADDRESS) IPv4() net.IP {
|
||||
ipBytes := make([]byte, 4)
|
||||
|
||||
binary.BigEndian.PutUint32(ipBytes, uint32(ip))
|
||||
|
||||
return ipBytes
|
||||
}
|
||||
|
||||
func (ip DHCP_IP_MASK) IPv4Mask() net.IPMask {
|
||||
ipBytes := make([]byte, 4)
|
||||
|
||||
binary.BigEndian.PutUint32(ipBytes, uint32(ip))
|
||||
|
||||
return ipBytes
|
||||
}
|
||||
|
||||
type DHCP_SUPER_SCOPE_TABLE struct {
|
||||
Count win32api.DWORD
|
||||
Entries *DHCP_SUPER_SCOPE_TABLE_ENTRY
|
||||
}
|
||||
|
||||
type DHCP_SUPER_SCOPE_TABLE_ENTRY struct {
|
||||
SubnetAddress DHCP_IP_ADDRESS
|
||||
SuperScopeNumber win32api.DWORD
|
||||
NextInSuperScope win32api.DWORD
|
||||
SuperScopeName win32api.LPWSTR
|
||||
}
|
||||
|
||||
// DHCP_SUBNET_INFO https://learn.microsoft.com/de-de/windows/win32/api/dhcpsapi/ns-dhcpsapi-dhcp_subnet_info
|
||||
type DHCP_SUBNET_INFO struct {
|
||||
SubnetAddress DHCP_IP_ADDRESS
|
||||
SubnetMask DHCP_IP_MASK
|
||||
SubnetName win32api.LPWSTR
|
||||
SubnetComment win32api.LPWSTR
|
||||
PrimaryHost DHCP_HOST_INFO
|
||||
SubnetState DHCP_SUBNET_STATE
|
||||
}
|
||||
|
||||
type DHCP_HOST_INFO struct {
|
||||
IpAddress DHCP_IP_ADDRESS
|
||||
NetBiosName win32api.LPWSTR
|
||||
HostName win32api.LPWSTR
|
||||
}
|
||||
|
||||
// DHCP_SUBNET_STATE https://learn.microsoft.com/de-de/windows/win32/api/dhcpsapi/ne-dhcpsapi-dhcp_subnet_state
|
||||
type DHCP_SUBNET_STATE uint32
|
||||
|
||||
const (
|
||||
DhcpSubnetEnabled DHCP_SUBNET_STATE = 0
|
||||
DhcpSubnetDisabled DHCP_SUBNET_STATE = 1
|
||||
DhcpSubnetEnabledSwitched DHCP_SUBNET_STATE = 2
|
||||
DhcpSubnetDisabledSwitched DHCP_SUBNET_STATE = 3
|
||||
DhcpSubnetInvalidState DHCP_SUBNET_STATE = 4
|
||||
)
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var DHCP_SUBNET_STATE_NAMES = map[DHCP_SUBNET_STATE]string{
|
||||
DhcpSubnetEnabled: "Enabled",
|
||||
DhcpSubnetDisabled: "Disabled",
|
||||
DhcpSubnetEnabledSwitched: "EnabledSwitched",
|
||||
DhcpSubnetDisabledSwitched: "DisabledSwitched",
|
||||
DhcpSubnetInvalidState: "InvalidState",
|
||||
}
|
||||
|
||||
type DHCP_FAILOVER_STATISTICS struct {
|
||||
NumAddr win32api.DWORD
|
||||
AddrFree win32api.DWORD
|
||||
AddrInUse win32api.DWORD
|
||||
PartnerAddrFree win32api.DWORD
|
||||
ThisAddrFree win32api.DWORD
|
||||
PartnerAddrInUse win32api.DWORD
|
||||
ThisAddrInUse win32api.DWORD
|
||||
}
|
||||
|
||||
type DHCP_MIB_INFO_V5 struct {
|
||||
Discovers win32api.DWORD
|
||||
Offers win32api.DWORD
|
||||
Requests win32api.DWORD
|
||||
Acks win32api.DWORD
|
||||
Naks win32api.DWORD
|
||||
Declines win32api.DWORD
|
||||
Releases win32api.DWORD
|
||||
ServerStartTime win32api.DATE_TIME
|
||||
QtnNumLeases win32api.DWORD
|
||||
QtnPctQtnLeases win32api.DWORD
|
||||
QtnProbationLeases win32api.DWORD
|
||||
QtnNonQtnLeases win32api.DWORD
|
||||
QtnExemptLeases win32api.DWORD
|
||||
QtnCapableClients win32api.DWORD
|
||||
QtnIASErrors win32api.DWORD
|
||||
DelayedOffers win32api.DWORD
|
||||
ScopesWithDelayedOffers win32api.DWORD
|
||||
Scopes win32api.DWORD
|
||||
ScopeInfo *DHCP_SUBNET_MIB_INFO_V5
|
||||
}
|
||||
|
||||
type DHCP_SUBNET_MIB_INFO_V5 struct {
|
||||
Subnet DHCP_IP_ADDRESS
|
||||
NumAddressesInUse win32api.DWORD
|
||||
NumAddressesFree win32api.DWORD
|
||||
NumPendingOffers win32api.DWORD
|
||||
}
|
||||
15
internal/headers/win32api/types.go
Normal file
15
internal/headers/win32api/types.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package win32api
|
||||
|
||||
import "golang.org/x/sys/windows"
|
||||
|
||||
type (
|
||||
DATE_TIME = windows.Filetime
|
||||
DWORD = uint32
|
||||
LPWSTR struct {
|
||||
*uint16
|
||||
}
|
||||
)
|
||||
|
||||
func (s LPWSTR) String() string {
|
||||
return windows.UTF16PtrToString(s.uint16)
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
@@ -82,8 +81,7 @@ func New(logger *slog.Logger, metricCollectors *collector.Collection, options *O
|
||||
|
||||
func (c *MetricsHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
logger := c.logger.With(
|
||||
slog.Any("remote", r.RemoteAddr),
|
||||
slog.Any("correlation_id", uuid.New().String()),
|
||||
slog.String("remote", r.RemoteAddr),
|
||||
)
|
||||
|
||||
scrapeTimeout := c.getScrapeTimeout(logger, r)
|
||||
|
||||
@@ -17,53 +17,41 @@
|
||||
package eventlog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
// NeLogOemCode is a generic error log entry for OEMs to use to
|
||||
// elog errors from OEM value added services.
|
||||
// See: https://github.com/microsoft/win32metadata/blob/2f3c5282ce1024a712aeccd90d3aa50bf7a49e27/generation/WinSDK/RecompiledIdlHeaders/um/LMErrlog.h#L824-L845
|
||||
NeLogOemCode = uint32(3299)
|
||||
"golang.org/x/sys/windows/svc/eventlog"
|
||||
)
|
||||
|
||||
// Interface guard.
|
||||
var _ io.Writer = (*Writer)(nil)
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var EmptyStringUTF16 uint16
|
||||
var reStripTimeAndLevel = regexp.MustCompile(`^time=\S+ level=\S+ `)
|
||||
|
||||
type Writer struct {
|
||||
handle windows.Handle
|
||||
handle *eventlog.Log
|
||||
}
|
||||
|
||||
// NewEventLogWriter returns a new Writer which writes to Windows EventLog.
|
||||
func NewEventLogWriter(handle windows.Handle) *Writer {
|
||||
// NewEventLogWriter returns a new Writer, which writes to Windows EventLog.
|
||||
func NewEventLogWriter(handle *eventlog.Log) *Writer {
|
||||
return &Writer{handle: handle}
|
||||
}
|
||||
|
||||
func (w *Writer) Write(p []byte) (int, error) {
|
||||
var eType uint16
|
||||
var err error
|
||||
|
||||
msg := strings.TrimSpace(string(p))
|
||||
eventLogMsg := reStripTimeAndLevel.ReplaceAllString(msg, "")
|
||||
|
||||
switch {
|
||||
case bytes.Contains(p, []byte(" level=error")) || bytes.Contains(p, []byte(`"level":"error"`)):
|
||||
eType = windows.EVENTLOG_ERROR_TYPE
|
||||
case bytes.Contains(p, []byte(" level=warn")) || bytes.Contains(p, []byte(`"level":"warn"`)):
|
||||
eType = windows.EVENTLOG_WARNING_TYPE
|
||||
case strings.Contains(msg, " level=ERROR") || strings.Contains(msg, `"level":"error"`):
|
||||
err = w.handle.Error(102, eventLogMsg)
|
||||
case strings.Contains(msg, " level=WARN") || strings.Contains(msg, `"level":"warn"`):
|
||||
err = w.handle.Warning(101, eventLogMsg)
|
||||
default:
|
||||
eType = windows.EVENTLOG_INFORMATION_TYPE
|
||||
err = w.handle.Info(100, eventLogMsg)
|
||||
}
|
||||
|
||||
msg, err := windows.UTF16PtrFromString(string(p))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error convert string to UTF-16: %w", err)
|
||||
}
|
||||
|
||||
ss := []*uint16{msg, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16, &EmptyStringUTF16}
|
||||
|
||||
return len(p), windows.ReportEvent(w.handle, eType, 0, NeLogOemCode, 0, 9, 0, &ss[0], nil)
|
||||
return len(p), err
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/log/eventlog"
|
||||
"github.com/prometheus/common/promslog"
|
||||
"golang.org/x/sys/windows"
|
||||
wineventlog "golang.org/x/sys/windows/svc/eventlog"
|
||||
)
|
||||
|
||||
// AllowedFile is a settable identifier for the output file that the logger can have.
|
||||
@@ -51,12 +51,12 @@ func (f *AllowedFile) Set(s string) error {
|
||||
case "stderr":
|
||||
f.w = os.Stderr
|
||||
case "eventlog":
|
||||
handle, err := windows.RegisterEventSource(nil, windows.StringToUTF16Ptr("windows_exporter"))
|
||||
eventLog, err := wineventlog.Open("windows_exporter")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open event log: %w", err)
|
||||
}
|
||||
|
||||
f.w = eventlog.NewEventLogWriter(handle)
|
||||
f.w = eventlog.NewEventLogWriter(eventLog)
|
||||
default:
|
||||
file, err := os.OpenFile(s, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o200)
|
||||
if err != nil {
|
||||
|
||||
@@ -138,6 +138,10 @@ func (o *OperationUnmarshalCallbacks) InstanceResult(
|
||||
|
||||
element, err := instance.GetElement(miTag)
|
||||
if err != nil {
|
||||
if errors.Is(err, MI_RESULT_NO_SUCH_PROPERTY) {
|
||||
continue
|
||||
}
|
||||
|
||||
o.errCh <- fmt.Errorf("failed to get element %s: %w", miTag, err)
|
||||
|
||||
return 0
|
||||
|
||||
@@ -172,6 +172,12 @@ func NewCollectorWithReflection(resultType CounterType, object string, instances
|
||||
continue
|
||||
}
|
||||
|
||||
if bufLen == 0 {
|
||||
errs = append(errs, errors.New("GetCounterInfo: buffer length is zero"))
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
buf := make([]byte, bufLen)
|
||||
if ret := GetCounterInfo(counterHandle, 0, &bufLen, &buf[0]); ret != ErrorSuccess {
|
||||
errs = append(errs, fmt.Errorf("GetCounterInfo: %w", NewPdhError(ret)))
|
||||
@@ -390,7 +396,7 @@ func (c *Collector) collectWorkerRaw() {
|
||||
case PERF_ELAPSED_TIME:
|
||||
dv.Index(index).
|
||||
Field(counter.FieldIndexValue).
|
||||
SetFloat(float64((item.RawValue.FirstValue - WindowsEpoch) / counter.Frequency))
|
||||
SetFloat(float64((item.RawValue.SecondValue - item.RawValue.FirstValue) / counter.Frequency))
|
||||
case PERF_100NSEC_TIMER, PERF_PRECISION_100NS_TIMER:
|
||||
dv.Index(index).
|
||||
Field(counter.FieldIndexValue).
|
||||
|
||||
@@ -16,10 +16,5 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
BuildNumberWindowsServer2025 uint32 = 26100
|
||||
BuildNumberWindowsServer2022 uint32 = 20348
|
||||
BuildNumberWindowsServer2019 uint32 = 17763
|
||||
BuildNumberWindowsServer2016 uint32 = 14393
|
||||
|
||||
Namespace = "windows"
|
||||
)
|
||||
|
||||
@@ -105,7 +105,7 @@ test_alpha_total 42
|
||||
# TYPE windows_cs_hostname gauge
|
||||
# HELP windows_cs_logical_processors Deprecated: Use windows_cpu_logical_processor instead
|
||||
# TYPE windows_cs_logical_processors gauge
|
||||
# HELP windows_cs_physical_memory_bytes Deprecated: Use windows_physical_memory_total_bytes instead
|
||||
# HELP windows_cs_physical_memory_bytes Deprecated: Use windows_memory_physical_total_bytes instead
|
||||
# TYPE windows_cs_physical_memory_bytes gauge
|
||||
# HELP windows_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, goversion from which windows_exporter was built, and the goos and goarch for the build.
|
||||
# TYPE windows_exporter_build_info gauge
|
||||
|
||||
Reference in New Issue
Block a user