mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +00:00
iis: Add HTTP Service Request Queues (#1948)
Co-authored-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
committed by
GitHub
parent
036c858355
commit
3e8693f1e3
@@ -130,6 +130,10 @@ If given, an application needs to *not* match the exclude regexp in order for th
|
|||||||
| `windows_iis_server_output_cache_hits_total` | Total number of successful lookups in output cache (since service startup) | counter | None |
|
| `windows_iis_server_output_cache_hits_total` | Total number of successful lookups in output cache (since service startup) | counter | None |
|
||||||
| `windows_iis_server_output_cache_items_flushed_total` | Total number of items flushed from output cache (since service startup) | counter | None |
|
| `windows_iis_server_output_cache_items_flushed_total` | Total number of items flushed from output cache (since service startup) | counter | None |
|
||||||
| `windows_iis_server_output_cache_flushes_total` | Total number of flushes of output cache (since service startup) | counter | None |
|
| `windows_iis_server_output_cache_flushes_total` | Total number of flushes of output cache (since service startup) | counter | None |
|
||||||
|
| `http_requests_current_queue_size` | Http Request Current queue size | counter | None |
|
||||||
|
| `http_request_total_rejected_request` | Http Request total rejected request | counter | None |
|
||||||
|
| `http_requests_max_queue_item_age` | Http Request Max queue Item age | counter | None |
|
||||||
|
| `http_requests_arrival_rate` | Http requests Arrival Rate | counter | None |
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||||
|
|||||||
@@ -53,8 +53,11 @@ type Collector struct {
|
|||||||
config Config
|
config Config
|
||||||
iisVersion simpleVersion
|
iisVersion simpleVersion
|
||||||
|
|
||||||
|
logger *slog.Logger
|
||||||
|
|
||||||
info *prometheus.Desc
|
info *prometheus.Desc
|
||||||
collectorWebService
|
collectorWebService
|
||||||
|
collectorHttpServiceRequestQueues
|
||||||
collectorAppPoolWAS
|
collectorAppPoolWAS
|
||||||
collectorW3SVCW3WP
|
collectorW3SVCW3WP
|
||||||
collectorWebServiceCache
|
collectorWebServiceCache
|
||||||
@@ -150,6 +153,7 @@ func (c *Collector) GetName() string {
|
|||||||
|
|
||||||
func (c *Collector) Close() error {
|
func (c *Collector) Close() error {
|
||||||
c.perfDataCollectorWebService.Close()
|
c.perfDataCollectorWebService.Close()
|
||||||
|
c.perfDataCollectorHttpServiceRequestQueues.Close()
|
||||||
c.perfDataCollectorAppPoolWAS.Close()
|
c.perfDataCollectorAppPoolWAS.Close()
|
||||||
c.w3SVCW3WPPerfDataCollector.Close()
|
c.w3SVCW3WPPerfDataCollector.Close()
|
||||||
c.serviceCachePerfDataCollector.Close()
|
c.serviceCachePerfDataCollector.Close()
|
||||||
@@ -158,9 +162,9 @@ func (c *Collector) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
||||||
logger = logger.With(slog.String("collector", Name))
|
c.logger = logger.With(slog.String("collector", Name))
|
||||||
|
|
||||||
c.iisVersion = c.getIISVersion(logger)
|
c.iisVersion = c.getIISVersion()
|
||||||
|
|
||||||
c.info = prometheus.NewDesc(
|
c.info = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
prometheus.BuildFQName(types.Namespace, Name, "info"),
|
||||||
@@ -175,6 +179,10 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
|
|||||||
errs = append(errs, fmt.Errorf("failed to build Web Service collector: %w", err))
|
errs = append(errs, fmt.Errorf("failed to build Web Service collector: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.buildHttpServiceRequestQueues(); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("failed to build Http Service collector: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.buildAppPoolWAS(); err != nil {
|
if err := c.buildAppPoolWAS(); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to build APP_POOL_WAS collector: %w", err))
|
errs = append(errs, fmt.Errorf("failed to build APP_POOL_WAS collector: %w", err))
|
||||||
}
|
}
|
||||||
@@ -195,10 +203,10 @@ type simpleVersion struct {
|
|||||||
minor uint64
|
minor uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) getIISVersion(logger *slog.Logger) simpleVersion {
|
func (c *Collector) getIISVersion() simpleVersion {
|
||||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\InetStp\`, registry.QUERY_VALUE)
|
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\InetStp\`, registry.QUERY_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("couldn't open registry to determine IIS version",
|
c.logger.Warn("couldn't open registry to determine IIS version",
|
||||||
slog.Any("err", err),
|
slog.Any("err", err),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -208,7 +216,7 @@ func (c *Collector) getIISVersion(logger *slog.Logger) simpleVersion {
|
|||||||
defer func() {
|
defer func() {
|
||||||
err = k.Close()
|
err = k.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Failed to close registry key",
|
c.logger.Warn("Failed to close registry key",
|
||||||
slog.Any("err", err),
|
slog.Any("err", err),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -216,7 +224,7 @@ func (c *Collector) getIISVersion(logger *slog.Logger) simpleVersion {
|
|||||||
|
|
||||||
major, _, err := k.GetIntegerValue("MajorVersion")
|
major, _, err := k.GetIntegerValue("MajorVersion")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Couldn't open registry to determine IIS version",
|
c.logger.Warn("Couldn't open registry to determine IIS version",
|
||||||
slog.Any("err", err),
|
slog.Any("err", err),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -225,14 +233,14 @@ func (c *Collector) getIISVersion(logger *slog.Logger) simpleVersion {
|
|||||||
|
|
||||||
minor, _, err := k.GetIntegerValue("MinorVersion")
|
minor, _, err := k.GetIntegerValue("MinorVersion")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("Couldn't open registry to determine IIS version",
|
c.logger.Warn("Couldn't open registry to determine IIS version",
|
||||||
slog.Any("err", err),
|
slog.Any("err", err),
|
||||||
)
|
)
|
||||||
|
|
||||||
return simpleVersion{}
|
return simpleVersion{}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug(fmt.Sprintf("Detected IIS %d.%d\n", major, minor))
|
c.logger.Debug(fmt.Sprintf("Detected IIS %d.%d\n", major, minor))
|
||||||
|
|
||||||
return simpleVersion{
|
return simpleVersion{
|
||||||
major: major,
|
major: major,
|
||||||
@@ -255,6 +263,10 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
errs = append(errs, fmt.Errorf("failed to collect Web Service metrics: %w", err))
|
errs = append(errs, fmt.Errorf("failed to collect Web Service metrics: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.collectHttpServiceRequestQueues(ch); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("failed to collect Http Service Request Queues metrics: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.collectAppPoolWAS(ch); err != nil {
|
if err := c.collectAppPoolWAS(ch); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to collect APP_POOL_WAS metrics: %w", err))
|
errs = append(errs, fmt.Errorf("failed to collect APP_POOL_WAS metrics: %w", err))
|
||||||
}
|
}
|
||||||
|
|||||||
134
internal/collector/iis/iis_http_service_request_queues.go
Normal file
134
internal/collector/iis/iis_http_service_request_queues.go
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
// 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 iis
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||||
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type collectorHttpServiceRequestQueues struct {
|
||||||
|
perfDataCollectorHttpServiceRequestQueues *pdh.Collector
|
||||||
|
perfDataObjectHttpServiceRequestQueues []perfDataCounterValuesHttpServiceRequestQueues
|
||||||
|
|
||||||
|
httpRequestQueuesCurrentQueueSize *prometheus.Desc
|
||||||
|
httpRequestQueuesTotalRejectedRequest *prometheus.Desc
|
||||||
|
httpRequestQueuesMaxQueueItemAge *prometheus.Desc
|
||||||
|
httpRequestQueuesArrivalRate *prometheus.Desc
|
||||||
|
}
|
||||||
|
|
||||||
|
type perfDataCounterValuesHttpServiceRequestQueues struct {
|
||||||
|
Name string
|
||||||
|
|
||||||
|
HttpRequestQueuesCurrentQueueSize float64 `perfdata:"CurrentQueueSize"`
|
||||||
|
HttpRequestQueuesTotalRejectedRequests float64 `perfdata:"RejectedRequests"`
|
||||||
|
HttpRequestQueuesMaxQueueItemAge float64 `perfdata:"MaxQueueItemAge"`
|
||||||
|
HttpRequestQueuesArrivalRate float64 `perfdata:"ArrivalRate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p perfDataCounterValuesHttpServiceRequestQueues) GetName() string {
|
||||||
|
return p.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Collector) buildHttpServiceRequestQueues() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
c.logger.Info("IIS/HttpServiceRequestQueues collector is in an experimental state! The configuration and metrics may change in future. Please report any issues.")
|
||||||
|
|
||||||
|
c.perfDataCollectorHttpServiceRequestQueues, err = pdh.NewCollector[perfDataCounterValuesHttpServiceRequestQueues](pdh.CounterTypeRaw, "HTTP Service Request Queues", pdh.InstancesAll)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create Http Service collector: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.httpRequestQueuesCurrentQueueSize = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "http_requests_current_queue_size"),
|
||||||
|
"Http Request Current Queue Size",
|
||||||
|
[]string{"site"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.httpRequestQueuesTotalRejectedRequest = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "http_request_total_rejected_request"),
|
||||||
|
"Http Request Total Rejected Request",
|
||||||
|
[]string{"site"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.httpRequestQueuesMaxQueueItemAge = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "http_requests_max_queue_item_age"),
|
||||||
|
"Http Request Max Queue Item Age. The values might be bogus if the queue is empty.",
|
||||||
|
[]string{"site"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
c.httpRequestQueuesArrivalRate = prometheus.NewDesc(
|
||||||
|
prometheus.BuildFQName(types.Namespace, Name, "http_requests_arrival_rate"),
|
||||||
|
"Http Request Arrival Rate",
|
||||||
|
[]string{"site"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Collector) collectHttpServiceRequestQueues(ch chan<- prometheus.Metric) error {
|
||||||
|
err := c.perfDataCollectorHttpServiceRequestQueues.Collect(&c.perfDataObjectHttpServiceRequestQueues)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to collect Http Service Request Queues metrics: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
deduplicateIISNames(c.perfDataObjectHttpServiceRequestQueues)
|
||||||
|
|
||||||
|
for _, data := range c.perfDataObjectHttpServiceRequestQueues {
|
||||||
|
if strings.HasPrefix(data.Name, "---") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.config.SiteExclude.MatchString(data.Name) || !c.config.SiteInclude.MatchString(data.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.httpRequestQueuesCurrentQueueSize,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
data.HttpRequestQueuesCurrentQueueSize,
|
||||||
|
data.Name,
|
||||||
|
)
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.httpRequestQueuesTotalRejectedRequest,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
data.HttpRequestQueuesTotalRejectedRequests,
|
||||||
|
data.Name,
|
||||||
|
)
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.httpRequestQueuesMaxQueueItemAge,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
data.HttpRequestQueuesMaxQueueItemAge,
|
||||||
|
data.Name,
|
||||||
|
)
|
||||||
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
c.httpRequestQueuesArrivalRate,
|
||||||
|
prometheus.GaugeValue,
|
||||||
|
data.HttpRequestQueuesArrivalRate,
|
||||||
|
data.Name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user