1
0
mirror of https://github.com/nginxinc/nginx-prometheus-exporter.git synced 2025-08-08 05:02:04 +03:00

Use timeout flag for context cancelation

This commit is contained in:
Luca Comellini
2024-09-30 19:48:43 -07:00
parent 9cd3941e7c
commit 487aac4b2a
4 changed files with 25 additions and 19 deletions

View File

@@ -47,10 +47,7 @@ func NewNginxClient(httpClient *http.Client, apiEndpoint string) *NginxClient {
} }
// GetStubStats fetches the stub_status metrics. // GetStubStats fetches the stub_status metrics.
func (client *NginxClient) GetStubStats() (*StubStats, error) { func (client *NginxClient) GetStubStats(ctx context.Context) (*StubStats, error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, client.apiEndpoint, nil) req, err := http.NewRequestWithContext(ctx, http.MethodGet, client.apiEndpoint, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create a get request: %w", err) return nil, fmt.Errorf("failed to create a get request: %w", err)

View File

@@ -1,8 +1,10 @@
package collector package collector
import ( import (
"context"
"log/slog" "log/slog"
"sync" "sync"
"time"
"github.com/nginxinc/nginx-prometheus-exporter/client" "github.com/nginxinc/nginx-prometheus-exporter/client"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -14,14 +16,16 @@ type NginxCollector struct {
logger *slog.Logger logger *slog.Logger
nginxClient *client.NginxClient nginxClient *client.NginxClient
metrics map[string]*prometheus.Desc metrics map[string]*prometheus.Desc
timeout time.Duration
mutex sync.Mutex mutex sync.Mutex
} }
// NewNginxCollector creates an NginxCollector. // NewNginxCollector creates an NginxCollector.
func NewNginxCollector(nginxClient *client.NginxClient, namespace string, constLabels map[string]string, logger *slog.Logger) *NginxCollector { func NewNginxCollector(nginxClient *client.NginxClient, namespace string, constLabels map[string]string, logger *slog.Logger, timeout time.Duration) *NginxCollector {
return &NginxCollector{ return &NginxCollector{
nginxClient: nginxClient, nginxClient: nginxClient,
logger: logger, logger: logger,
timeout: timeout,
metrics: map[string]*prometheus.Desc{ metrics: map[string]*prometheus.Desc{
"connections_active": newGlobalMetric(namespace, "connections_active", "Active client connections", constLabels), "connections_active": newGlobalMetric(namespace, "connections_active", "Active client connections", constLabels),
"connections_accepted": newGlobalMetric(namespace, "connections_accepted", "Accepted client connections", constLabels), "connections_accepted": newGlobalMetric(namespace, "connections_accepted", "Accepted client connections", constLabels),
@@ -50,7 +54,10 @@ func (c *NginxCollector) Collect(ch chan<- prometheus.Metric) {
c.mutex.Lock() // To protect metrics from concurrent collects c.mutex.Lock() // To protect metrics from concurrent collects
defer c.mutex.Unlock() defer c.mutex.Unlock()
stats, err := c.nginxClient.GetStubStats() ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
defer cancel()
stats, err := c.nginxClient.GetStubStats(ctx)
if err != nil { if err != nil {
c.upMetric.Set(nginxDown) c.upMetric.Set(nginxDown)
ch <- c.upMetric ch <- c.upMetric

View File

@@ -6,6 +6,7 @@ import (
"log/slog" "log/slog"
"strconv" "strconv"
"sync" "sync"
"time"
plusclient "github.com/nginxinc/nginx-plus-go-client/v2/client" plusclient "github.com/nginxinc/nginx-plus-go-client/v2/client"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@@ -31,11 +32,11 @@ type LabelUpdater interface {
// NginxPlusCollector collects NGINX Plus metrics. It implements prometheus.Collector interface. // NginxPlusCollector collects NGINX Plus metrics. It implements prometheus.Collector interface.
type NginxPlusCollector struct { type NginxPlusCollector struct {
upMetric prometheus.Gauge nginxClient *plusclient.NginxClient
logger *slog.Logger logger *slog.Logger
upMetric prometheus.Gauge
cacheZoneMetrics map[string]*prometheus.Desc cacheZoneMetrics map[string]*prometheus.Desc
workerMetrics map[string]*prometheus.Desc workerMetrics map[string]*prometheus.Desc
nginxClient *plusclient.NginxClient
streamServerZoneMetrics map[string]*prometheus.Desc streamServerZoneMetrics map[string]*prometheus.Desc
streamZoneSyncMetrics map[string]*prometheus.Desc streamZoneSyncMetrics map[string]*prometheus.Desc
streamUpstreamMetrics map[string]*prometheus.Desc streamUpstreamMetrics map[string]*prometheus.Desc
@@ -47,16 +48,17 @@ type NginxPlusCollector struct {
streamLimitConnectionMetrics map[string]*prometheus.Desc streamLimitConnectionMetrics map[string]*prometheus.Desc
upstreamServerMetrics map[string]*prometheus.Desc upstreamServerMetrics map[string]*prometheus.Desc
upstreamMetrics map[string]*prometheus.Desc upstreamMetrics map[string]*prometheus.Desc
streamUpstreamServerPeerLabels map[string][]string
serverZoneMetrics map[string]*prometheus.Desc serverZoneMetrics map[string]*prometheus.Desc
totalMetrics map[string]*prometheus.Desc
streamUpstreamServerPeerLabels map[string][]string
upstreamServerLabels map[string][]string upstreamServerLabels map[string][]string
streamUpstreamServerLabels map[string][]string streamUpstreamServerLabels map[string][]string
serverZoneLabels map[string][]string serverZoneLabels map[string][]string
streamServerZoneLabels map[string][]string streamServerZoneLabels map[string][]string
upstreamServerPeerLabels map[string][]string upstreamServerPeerLabels map[string][]string
cacheZoneLabels map[string][]string cacheZoneLabels map[string][]string
totalMetrics map[string]*prometheus.Desc
variableLabelNames VariableLabelNames variableLabelNames VariableLabelNames
timeout time.Duration
variableLabelsMutex sync.RWMutex variableLabelsMutex sync.RWMutex
mutex sync.Mutex mutex sync.Mutex
} }
@@ -256,7 +258,7 @@ func NewVariableLabelNames(upstreamServerVariableLabelNames []string, serverZone
} }
// NewNginxPlusCollector creates an NginxPlusCollector. // NewNginxPlusCollector creates an NginxPlusCollector.
func NewNginxPlusCollector(nginxClient *plusclient.NginxClient, namespace string, variableLabelNames VariableLabelNames, constLabels map[string]string, logger *slog.Logger) *NginxPlusCollector { func NewNginxPlusCollector(nginxClient *plusclient.NginxClient, namespace string, variableLabelNames VariableLabelNames, constLabels map[string]string, logger *slog.Logger, timeout time.Duration) *NginxPlusCollector {
upstreamServerVariableLabelNames := variableLabelNames.UpstreamServerVariableLabelNames upstreamServerVariableLabelNames := variableLabelNames.UpstreamServerVariableLabelNames
streamUpstreamServerVariableLabelNames := variableLabelNames.StreamUpstreamServerVariableLabelNames streamUpstreamServerVariableLabelNames := variableLabelNames.StreamUpstreamServerVariableLabelNames
@@ -273,6 +275,7 @@ func NewNginxPlusCollector(nginxClient *plusclient.NginxClient, namespace string
cacheZoneLabels: make(map[string][]string), cacheZoneLabels: make(map[string][]string),
nginxClient: nginxClient, nginxClient: nginxClient,
logger: logger, logger: logger,
timeout: timeout,
totalMetrics: map[string]*prometheus.Desc{ totalMetrics: map[string]*prometheus.Desc{
"connections_accepted": newGlobalMetric(namespace, "connections_accepted", "Accepted client connections", constLabels), "connections_accepted": newGlobalMetric(namespace, "connections_accepted", "Accepted client connections", constLabels),
"connections_dropped": newGlobalMetric(namespace, "connections_dropped", "Dropped client connections", constLabels), "connections_dropped": newGlobalMetric(namespace, "connections_dropped", "Dropped client connections", constLabels),
@@ -623,8 +626,10 @@ func (c *NginxPlusCollector) Collect(ch chan<- prometheus.Metric) {
c.mutex.Lock() // To protect metrics from concurrent collects c.mutex.Lock() // To protect metrics from concurrent collects
defer c.mutex.Unlock() defer c.mutex.Unlock()
// FIXME: https://github.com/nginxinc/nginx-prometheus-exporter/issues/858 ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
stats, err := c.nginxClient.GetStats(context.TODO()) defer cancel()
stats, err := c.nginxClient.GetStats(ctx)
if err != nil { if err != nil {
c.upMetric.Set(nginxDown) c.upMetric.Set(nginxDown)
ch <- c.upMetric ch <- c.upMetric

View File

@@ -220,9 +220,7 @@ func main() {
_ = srv.Shutdown(srvCtx) _ = srv.Shutdown(srvCtx)
} }
func registerCollector(logger *slog.Logger, transport *http.Transport, func registerCollector(logger *slog.Logger, transport *http.Transport, addr string, labels map[string]string) {
addr string, labels map[string]string,
) {
if strings.HasPrefix(addr, "unix:") { if strings.HasPrefix(addr, "unix:") {
socketPath, requestPath, err := parseUnixSocketAddress(addr) socketPath, requestPath, err := parseUnixSocketAddress(addr)
if err != nil { if err != nil {
@@ -239,7 +237,6 @@ func registerCollector(logger *slog.Logger, transport *http.Transport,
userAgent := fmt.Sprintf("NGINX-Prometheus-Exporter/v%v", common_version.Version) userAgent := fmt.Sprintf("NGINX-Prometheus-Exporter/v%v", common_version.Version)
httpClient := &http.Client{ httpClient := &http.Client{
Timeout: *timeout,
Transport: &userAgentRoundTripper{ Transport: &userAgentRoundTripper{
agent: userAgent, agent: userAgent,
rt: transport, rt: transport,
@@ -253,10 +250,10 @@ func registerCollector(logger *slog.Logger, transport *http.Transport,
os.Exit(1) os.Exit(1)
} }
variableLabelNames := collector.NewVariableLabelNames(nil, nil, nil, nil, nil, nil, nil) variableLabelNames := collector.NewVariableLabelNames(nil, nil, nil, nil, nil, nil, nil)
prometheus.MustRegister(collector.NewNginxPlusCollector(plusClient, "nginxplus", variableLabelNames, labels, logger)) prometheus.MustRegister(collector.NewNginxPlusCollector(plusClient, "nginxplus", variableLabelNames, labels, logger, *timeout))
} else { } else {
ossClient := client.NewNginxClient(httpClient, addr) ossClient := client.NewNginxClient(httpClient, addr)
prometheus.MustRegister(collector.NewNginxCollector(ossClient, "nginx", labels, logger)) prometheus.MustRegister(collector.NewNginxCollector(ossClient, "nginx", labels, logger, *timeout))
} }
} }