Files
windows_exporter/internal/collector/iis/iis_web_service.go
Jan-Otto Kröpke 1a4c6c5ce7 feat: Tolerate collector failures (#1769)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2024-11-25 21:27:31 +01:00

530 lines
19 KiB
Go

// Copyright 2024 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"
"github.com/prometheus-community/windows_exporter/internal/perfdata"
"github.com/prometheus-community/windows_exporter/internal/types"
"github.com/prometheus/client_golang/prometheus"
)
type collectorWebService struct {
perfDataCollectorWebService *perfdata.Collector
webServiceCurrentAnonymousUsers *prometheus.Desc
webServiceCurrentBlockedAsyncIORequests *prometheus.Desc
webServiceCurrentCGIRequests *prometheus.Desc
webServiceCurrentConnections *prometheus.Desc
webServiceCurrentISAPIExtensionRequests *prometheus.Desc
webServiceCurrentNonAnonymousUsers *prometheus.Desc
webServiceServiceUptime *prometheus.Desc
webServiceTotalBytesReceived *prometheus.Desc
webServiceTotalBytesSent *prometheus.Desc
webServiceTotalAnonymousUsers *prometheus.Desc
webServiceTotalBlockedAsyncIORequests *prometheus.Desc
webServiceTotalCGIRequests *prometheus.Desc
webServiceTotalConnectionAttemptsAllInstances *prometheus.Desc
webServiceTotalRequests *prometheus.Desc
webServiceTotalFilesReceived *prometheus.Desc
webServiceTotalFilesSent *prometheus.Desc
webServiceTotalISAPIExtensionRequests *prometheus.Desc
webServiceTotalLockedErrors *prometheus.Desc
webServiceTotalLogonAttempts *prometheus.Desc
webServiceTotalNonAnonymousUsers *prometheus.Desc
webServiceTotalNotFoundErrors *prometheus.Desc
webServiceTotalRejectedAsyncIORequests *prometheus.Desc
}
const (
webServiceCurrentAnonymousUsers = "Current Anonymous Users"
webServiceCurrentBlockedAsyncIORequests = "Current Blocked Async I/O Requests"
webServiceCurrentCGIRequests = "Current CGI Requests"
webServiceCurrentConnections = "Current Connections"
webServiceCurrentISAPIExtensionRequests = "Current ISAPI Extension Requests"
webServiceCurrentNonAnonymousUsers = "Current NonAnonymous Users"
webServiceServiceUptime = "Service Uptime"
webServiceTotalBytesReceived = "Total Bytes Received"
webServiceTotalBytesSent = "Total Bytes Sent"
webServiceTotalAnonymousUsers = "Total Anonymous Users"
webServiceTotalBlockedAsyncIORequests = "Total Blocked Async I/O Requests"
webServiceTotalCGIRequests = "Total CGI Requests"
webServiceTotalConnectionAttemptsAllInstances = "Total Connection Attempts (all instances)"
webServiceTotalFilesReceived = "Total Files Received"
webServiceTotalFilesSent = "Total Files Sent"
webServiceTotalISAPIExtensionRequests = "Total ISAPI Extension Requests"
webServiceTotalLockedErrors = "Total Locked Errors"
webServiceTotalLogonAttempts = "Total Logon Attempts"
webServiceTotalNonAnonymousUsers = "Total NonAnonymous Users"
webServiceTotalNotFoundErrors = "Total Not Found Errors"
webServiceTotalRejectedAsyncIORequests = "Total Rejected Async I/O Requests"
webServiceTotalCopyRequests = "Total Copy Requests"
webServiceTotalDeleteRequests = "Total Delete Requests"
webServiceTotalGetRequests = "Total Get Requests"
webServiceTotalHeadRequests = "Total Head Requests"
webServiceTotalLockRequests = "Total Lock Requests"
webServiceTotalMkcolRequests = "Total Mkcol Requests"
webServiceTotalMoveRequests = "Total Move Requests"
webServiceTotalOptionsRequests = "Total Options Requests"
webServiceTotalOtherRequests = "Total Other Request Methods"
webServiceTotalPostRequests = "Total Post Requests"
webServiceTotalPropfindRequests = "Total Propfind Requests"
webServiceTotalProppatchRequests = "Total Proppatch Requests"
webServiceTotalPutRequests = "Total Put Requests"
webServiceTotalSearchRequests = "Total Search Requests"
webServiceTotalTraceRequests = "Total Trace Requests"
webServiceTotalUnlockRequests = "Total Unlock Requests"
)
func (c *Collector) buildWebService() error {
var err error
c.perfDataCollectorWebService, err = perfdata.NewCollector("Web Service", perfdata.InstancesAll, []string{
webServiceCurrentAnonymousUsers,
webServiceCurrentBlockedAsyncIORequests,
webServiceCurrentCGIRequests,
webServiceCurrentConnections,
webServiceCurrentISAPIExtensionRequests,
webServiceCurrentNonAnonymousUsers,
webServiceServiceUptime,
webServiceTotalBytesReceived,
webServiceTotalBytesSent,
webServiceTotalAnonymousUsers,
webServiceTotalBlockedAsyncIORequests,
webServiceTotalCGIRequests,
webServiceTotalConnectionAttemptsAllInstances,
webServiceTotalFilesReceived,
webServiceTotalFilesSent,
webServiceTotalISAPIExtensionRequests,
webServiceTotalLockedErrors,
webServiceTotalLogonAttempts,
webServiceTotalNonAnonymousUsers,
webServiceTotalNotFoundErrors,
webServiceTotalRejectedAsyncIORequests,
webServiceTotalCopyRequests,
webServiceTotalDeleteRequests,
webServiceTotalGetRequests,
webServiceTotalHeadRequests,
webServiceTotalLockRequests,
webServiceTotalMkcolRequests,
webServiceTotalMoveRequests,
webServiceTotalOptionsRequests,
webServiceTotalOtherRequests,
webServiceTotalPostRequests,
webServiceTotalPropfindRequests,
webServiceTotalProppatchRequests,
webServiceTotalPutRequests,
webServiceTotalSearchRequests,
webServiceTotalTraceRequests,
webServiceTotalUnlockRequests,
})
if err != nil {
return fmt.Errorf("failed to create Web Service collector: %w", err)
}
c.webServiceCurrentAnonymousUsers = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "current_anonymous_users"),
"Number of users who currently have an anonymous connection using the Web service (WebService.CurrentAnonymousUsers)",
[]string{"site"},
nil,
)
c.webServiceCurrentBlockedAsyncIORequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "current_blocked_async_io_requests"),
"Current requests temporarily blocked due to bandwidth throttling settings (WebService.CurrentBlockedAsyncIORequests)",
[]string{"site"},
nil,
)
c.webServiceCurrentCGIRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "current_cgi_requests"),
"Current number of CGI requests being simultaneously processed by the Web service (WebService.CurrentCGIRequests)",
[]string{"site"},
nil,
)
c.webServiceCurrentConnections = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "current_connections"),
"Current number of connections established with the Web service (WebService.CurrentConnections)",
[]string{"site"},
nil,
)
c.webServiceCurrentISAPIExtensionRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "current_isapi_extension_requests"),
"Current number of ISAPI requests being simultaneously processed by the Web service (WebService.CurrentISAPIExtensionRequests)",
[]string{"site"},
nil,
)
c.webServiceCurrentNonAnonymousUsers = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "current_non_anonymous_users"),
"Number of users who currently have a non-anonymous connection using the Web service (WebService.CurrentNonAnonymousUsers)",
[]string{"site"},
nil,
)
c.webServiceServiceUptime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "service_uptime"),
"Number of seconds the WebService is up (WebService.ServiceUptime)",
[]string{"site"},
nil,
)
c.webServiceTotalBytesReceived = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "received_bytes_total"),
"Number of data bytes that have been received by the Web service (WebService.TotalBytesReceived)",
[]string{"site"},
nil,
)
c.webServiceTotalBytesSent = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "sent_bytes_total"),
"Number of data bytes that have been sent by the Web service (WebService.TotalBytesSent)",
[]string{"site"},
nil,
)
c.webServiceTotalAnonymousUsers = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "anonymous_users_total"),
"Total number of users who established an anonymous connection with the Web service (WebService.TotalAnonymousUsers)",
[]string{"site"},
nil,
)
c.webServiceTotalBlockedAsyncIORequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "blocked_async_io_requests_total"),
"Total requests temporarily blocked due to bandwidth throttling settings (WebService.TotalBlockedAsyncIORequests)",
[]string{"site"},
nil,
)
c.webServiceTotalCGIRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "cgi_requests_total"),
"Total CGI requests is the total number of CGI requests (WebService.TotalCGIRequests)",
[]string{"site"},
nil,
)
c.webServiceTotalConnectionAttemptsAllInstances = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_attempts_all_instances_total"),
"Number of connections that have been attempted using the Web service (WebService.TotalConnectionAttemptsAllInstances)",
[]string{"site"},
nil,
)
c.webServiceTotalRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "requests_total"),
"Number of HTTP requests (WebService.TotalRequests)",
[]string{"site", "method"},
nil,
)
c.webServiceTotalFilesReceived = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "files_received_total"),
"Number of files received by the Web service (WebService.TotalFilesReceived)",
[]string{"site"},
nil,
)
c.webServiceTotalFilesSent = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "files_sent_total"),
"Number of files sent by the Web service (WebService.TotalFilesSent)",
[]string{"site"},
nil,
)
c.webServiceTotalISAPIExtensionRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ipapi_extension_requests_total"),
"ISAPI Extension Requests received (WebService.TotalISAPIExtensionRequests)",
[]string{"site"},
nil,
)
c.webServiceTotalLockedErrors = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "locked_errors_total"),
"Number of requests that couldn't be satisfied by the server because the requested resource was locked (WebService.TotalLockedErrors)",
[]string{"site"},
nil,
)
c.webServiceTotalLogonAttempts = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "logon_attempts_total"),
"Number of logons attempts to the Web Service (WebService.TotalLogonAttempts)",
[]string{"site"},
nil,
)
c.webServiceTotalNonAnonymousUsers = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "non_anonymous_users_total"),
"Number of users who established a non-anonymous connection with the Web service (WebService.TotalNonAnonymousUsers)",
[]string{"site"},
nil,
)
c.webServiceTotalNotFoundErrors = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "not_found_errors_total"),
"Number of requests that couldn't be satisfied by the server because the requested document could not be found (WebService.TotalNotFoundErrors)",
[]string{"site"},
nil,
)
c.webServiceTotalRejectedAsyncIORequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "rejected_async_io_requests_total"),
"Requests rejected due to bandwidth throttling settings (WebService.TotalRejectedAsyncIORequests)",
[]string{"site"},
nil,
)
return nil
}
func (c *Collector) collectWebService(ch chan<- prometheus.Metric) error {
perfData, err := c.perfDataCollectorWebService.Collect()
if err != nil {
return fmt.Errorf("failed to collect Web Service metrics: %w", err)
}
deduplicateIISNames(perfData)
for name, app := range perfData {
if c.config.SiteExclude.MatchString(name) || !c.config.SiteInclude.MatchString(name) {
continue
}
ch <- prometheus.MustNewConstMetric(
c.webServiceCurrentAnonymousUsers,
prometheus.GaugeValue,
app[webServiceCurrentAnonymousUsers].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceCurrentBlockedAsyncIORequests,
prometheus.GaugeValue,
app[webServiceCurrentBlockedAsyncIORequests].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceCurrentCGIRequests,
prometheus.GaugeValue,
app[webServiceCurrentCGIRequests].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceCurrentConnections,
prometheus.GaugeValue,
app[webServiceCurrentConnections].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceCurrentISAPIExtensionRequests,
prometheus.GaugeValue,
app[webServiceCurrentISAPIExtensionRequests].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceCurrentNonAnonymousUsers,
prometheus.GaugeValue,
app[webServiceCurrentNonAnonymousUsers].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceServiceUptime,
prometheus.GaugeValue,
app[webServiceServiceUptime].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalBytesReceived,
prometheus.CounterValue,
app[webServiceTotalBytesReceived].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalBytesSent,
prometheus.CounterValue,
app[webServiceTotalBytesSent].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalAnonymousUsers,
prometheus.CounterValue,
app[webServiceTotalAnonymousUsers].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalBlockedAsyncIORequests,
prometheus.CounterValue,
app[webServiceTotalBlockedAsyncIORequests].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalCGIRequests,
prometheus.CounterValue,
app[webServiceTotalCGIRequests].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalConnectionAttemptsAllInstances,
prometheus.CounterValue,
app[webServiceTotalConnectionAttemptsAllInstances].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalFilesReceived,
prometheus.CounterValue,
app[webServiceTotalFilesReceived].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalFilesSent,
prometheus.CounterValue,
app[webServiceTotalFilesSent].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalISAPIExtensionRequests,
prometheus.CounterValue,
app[webServiceTotalISAPIExtensionRequests].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalLockedErrors,
prometheus.CounterValue,
app[webServiceTotalLockedErrors].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalLogonAttempts,
prometheus.CounterValue,
app[webServiceTotalLogonAttempts].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalNonAnonymousUsers,
prometheus.CounterValue,
app[webServiceTotalNonAnonymousUsers].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalNotFoundErrors,
prometheus.CounterValue,
app[webServiceTotalNotFoundErrors].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRejectedAsyncIORequests,
prometheus.CounterValue,
app[webServiceTotalRejectedAsyncIORequests].FirstValue,
name,
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalOtherRequests].FirstValue,
name,
"other",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalCopyRequests].FirstValue,
name,
"COPY",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalDeleteRequests].FirstValue,
name,
"DELETE",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalGetRequests].FirstValue,
name,
"GET",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalHeadRequests].FirstValue,
name,
"HEAD",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalLockRequests].FirstValue,
name,
"LOCK",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalMkcolRequests].FirstValue,
name,
"MKCOL",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalMoveRequests].FirstValue,
name,
"MOVE",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalOptionsRequests].FirstValue,
name,
"OPTIONS",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalPostRequests].FirstValue,
name,
"POST",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalPropfindRequests].FirstValue,
name,
"PROPFIND",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalProppatchRequests].FirstValue,
name,
"PROPPATCH",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalPutRequests].FirstValue,
name,
"PUT",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalSearchRequests].FirstValue,
name,
"SEARCH",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalTraceRequests].FirstValue,
name,
"TRACE",
)
ch <- prometheus.MustNewConstMetric(
c.webServiceTotalRequests,
prometheus.CounterValue,
app[webServiceTotalUnlockRequests].FirstValue,
name,
"UNLOCK",
)
}
return nil
}