mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 18:19:04 +02:00
dhcp: query the distinct non-match denial counter (#2593)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Copyright The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build windows
|
||||
|
||||
package dhcp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDenialCounterValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := New(&Config{CollectorsEnabled: []string{subCollectorServerMetrics}})
|
||||
// Build creates descriptors before attempting to connect to the optional DHCP provider.
|
||||
_ = c.Build(slog.New(slog.DiscardHandler), nil)
|
||||
if c.perfDataCollector != nil {
|
||||
c.perfDataCollector.Close()
|
||||
}
|
||||
|
||||
c.perfDataCollector = denialFixture{
|
||||
"Denied due to match.": 7,
|
||||
"Denied due to nonmatch.": 11,
|
||||
}
|
||||
metrics := make(chan prometheus.Metric, 100)
|
||||
require.NoError(t, c.collectServerMetrics(metrics))
|
||||
close(metrics)
|
||||
|
||||
found := make(map[*prometheus.Desc]float64)
|
||||
|
||||
for metric := range metrics {
|
||||
var value dto.Metric
|
||||
require.NoError(t, metric.Write(&value))
|
||||
found[metric.Desc()] = value.GetCounter().GetValue()
|
||||
}
|
||||
|
||||
require.InDelta(t, 7, found[c.deniedDueToMatch], 1e-9)
|
||||
require.InDelta(t, 11, found[c.deniedDueToNonMatch], 1e-9)
|
||||
}
|
||||
|
||||
type denialFixture map[string]float64
|
||||
|
||||
func (f denialFixture) Collect(dst *[]perfDataCounterValues) error {
|
||||
var row perfDataCounterValues
|
||||
|
||||
value := reflect.ValueOf(&row).Elem()
|
||||
for _, field := range reflect.VisibleFields(value.Type()) {
|
||||
value.FieldByIndex(field.Index).SetFloat(f[field.Tag.Get("perfdata")])
|
||||
}
|
||||
|
||||
*dst = []perfDataCounterValues{row}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f denialFixture) Close() {}
|
||||
|
||||
func TestNativeDenialCounterNames(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logger := slog.New(slog.DiscardHandler)
|
||||
// Probe a known counter first so absence of the DHCP role can be skipped.
|
||||
probe, err := pdh.NewDynamicCollector(logger, pdh.CounterTypeRaw, "DHCP Server", nil, []string{"Acks/sec"})
|
||||
if probe != nil {
|
||||
t.Cleanup(probe.Close)
|
||||
}
|
||||
|
||||
if errors.Is(err, pdh.NewPdhError(pdh.CstatusNoObject)) || errors.Is(err, pdh.NewPdhError(pdh.CstatusNoCounter)) {
|
||||
t.Skip("DHCP Server performance counters are unavailable")
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
names := make([]string, 0, 2)
|
||||
|
||||
for _, fieldName := range []string{"DeniedDueToMatch", "DeniedDueToNonMatch"} {
|
||||
field, ok := reflect.TypeFor[perfDataCounterValues]().FieldByName(fieldName)
|
||||
require.True(t, ok)
|
||||
|
||||
names = append(names, field.Tag.Get("perfdata"))
|
||||
}
|
||||
|
||||
native, err := pdh.NewDynamicCollector(logger, pdh.CounterTypeRaw, "DHCP Server", nil, names)
|
||||
if native != nil {
|
||||
t.Cleanup(native.Close)
|
||||
}
|
||||
|
||||
require.NoError(t, err, "the production denial counter names must exist on the native provider")
|
||||
}
|
||||
|
||||
func TestCloseAfterInvalidSubcollectorBuild(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := New(&Config{CollectorsEnabled: []string{subCollectorServerMetrics, "invalid"}})
|
||||
require.Error(t, c.Build(slog.New(slog.DiscardHandler), nil))
|
||||
require.NoError(t, c.Close())
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"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"
|
||||
pdhtypes "github.com/prometheus-community/windows_exporter/internal/pdh/types"
|
||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
@@ -59,7 +60,7 @@ type Collector struct {
|
||||
|
||||
logger *slog.Logger
|
||||
|
||||
perfDataCollector *pdh.Collector[perfDataCounterValues]
|
||||
perfDataCollector pdhtypes.Collector[perfDataCounterValues]
|
||||
perfDataObject []perfDataCounterValues
|
||||
|
||||
acksTotal *prometheus.Desc
|
||||
@@ -143,7 +144,7 @@ func (c *Collector) GetName() string {
|
||||
}
|
||||
|
||||
func (c *Collector) Close() error {
|
||||
if slices.Contains(c.config.CollectorsEnabled, subCollectorServerMetrics) {
|
||||
if slices.Contains(c.config.CollectorsEnabled, subCollectorServerMetrics) && c.perfDataCollector != nil {
|
||||
c.perfDataCollector.Close()
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ type perfDataCounterValues struct {
|
||||
ConflictCheckQueueLength float64 `perfdata:"Conflict Check Queue Length"`
|
||||
DeclinesTotal float64 `perfdata:"Declines/sec"`
|
||||
DeniedDueToMatch float64 `perfdata:"Denied due to match."`
|
||||
DeniedDueToNonMatch float64 `perfdata:"Denied due to match."`
|
||||
DeniedDueToNonMatch float64 `perfdata:"Denied due to nonmatch."`
|
||||
DiscoversTotal float64 `perfdata:"Discovers/sec"`
|
||||
DuplicatesDroppedTotal float64 `perfdata:"Duplicates Dropped/sec"`
|
||||
FailoverBndAckReceivedTotal float64 `perfdata:"Failover: BndAck received/sec."`
|
||||
|
||||
Reference in New Issue
Block a user