Skip to content

Commit 0f8b7c9

Browse files
committed
Add metrics from NGINX Plus API version 9
Signed-off-by: Haywood Shannon <[email protected]>
1 parent d57f771 commit 0f8b7c9

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,17 @@ Name | Type | Description | Labels
362362
`nginxplus_cache_bypass_responses_written` | Counter | Total number of cache bypasses written to cache | `cache`
363363
`nginxplus_cache_bypass_bytes_written` | Counter | Total number of bytes written to cache from cache bypasses | `cache`
364364

365+
#### [Worker](hhttps://nginx.org/en/docs/http/ngx_http_api_module.html#workers)
366+
367+
Name | Type | Description | Labels
368+
----|-------|----|------------|
369+
`nginxplus_worker_connection_accepted` | Counter | The total number of accepted client connections | `id`, `pid` |
370+
`nginxplus_worker_connection_dropped` | Counter | The total number of accepted client connections | `id`, `pid` |
371+
`nginxplus_worker_connection_active` | Gauge | The current number of active client connections | `id`, `pid` |
372+
`nginxplus_worker_connection_idle` | Gauge | The current number of idle client connection | `id`, `pid` |
373+
`nginxplus_worker_http_requests_total` | Counter | The total number of client requests received by the worker process | `id`, `pid` |
374+
`nginxplus_worker_http_requests_current` | Gauge | The current number of client requests that are currently being processed by the worker process | `id`, `pid` |
375+
365376
Connect to the `/metrics` page of the running exporter to see the complete list of metrics along with their
366377
descriptions. Note: to see server zones related metrics you must configure [status
367378
zones](https://nginx.org/en/docs/http/ngx_http_status_module.html#status_zone) and to see upstream related metrics you

collector/nginx_plus.go

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package collector
22

33
import (
44
"fmt"
5+
"strconv"
56
"sync"
67

78
"github.com/go-kit/log"
@@ -26,6 +27,8 @@ type LabelUpdater interface {
2627
DeleteStreamServerZoneLabels(zoneNames []string)
2728
UpdateCacheZoneLabels(cacheLabelValues map[string][]string)
2829
DeleteCacheZoneLabels(cacheNames []string)
30+
UpdateWorkerLabels(workerLabelValues map[string][]string)
31+
DeleteWorkerLabels(workerNames []string)
2932
}
3033

3134
// NginxPlusCollector collects NGINX Plus metrics. It implements prometheus.Collector interface.
@@ -57,6 +60,8 @@ type NginxPlusCollector struct {
5760
cacheZoneLabels map[string][]string
5861
variableLabelsMutex sync.RWMutex
5962
logger log.Logger
63+
workerLabels map[string][]string
64+
workerMetrics map[string]*prometheus.Desc
6065
}
6166

6267
// UpdateUpstreamServerPeerLabels updates the Upstream Server Peer Labels
@@ -221,6 +226,30 @@ func (c *NginxPlusCollector) getStreamUpstreamServerPeerLabelValues(peer string)
221226
return c.streamUpstreamServerPeerLabels[peer]
222227
}
223228

229+
// UpdateWorkerLabels updates the Worker Labels
230+
func (c *NginxPlusCollector) UpdateWorkerLabels(workerLabelValues map[string][]string) {
231+
c.variableLabelsMutex.Lock()
232+
for k, v := range workerLabelValues {
233+
c.workerLabels[k] = v
234+
}
235+
c.variableLabelsMutex.Unlock()
236+
}
237+
238+
// DeleteWorkerLabels deletes the Worker Labels
239+
func (c *NginxPlusCollector) DeleteWorkerLabels(id []string) {
240+
c.variableLabelsMutex.Lock()
241+
for _, k := range id {
242+
delete(c.workerLabels, k)
243+
}
244+
c.variableLabelsMutex.Unlock()
245+
}
246+
247+
func (c *NginxPlusCollector) getWorkerLabelValues(id string) []string {
248+
c.variableLabelsMutex.RLock()
249+
defer c.variableLabelsMutex.RUnlock()
250+
return c.workerLabels[id]
251+
}
252+
224253
// VariableLabelNames holds all the variable label names for the different metrics
225254
type VariableLabelNames struct {
226255
UpstreamServerVariableLabelNames []string
@@ -230,11 +259,12 @@ type VariableLabelNames struct {
230259
StreamServerZoneVariableLabelNames []string
231260
StreamUpstreamServerVariableLabelNames []string
232261
CacheZoneLabelNames []string
262+
WorkerPIDVariableLabelNames []string
233263
}
234264

235-
// NewVariableLabels creates a new struct for VariableNames for the collector
265+
// NewVariableLabelNames NewVariableLabels creates a new struct for VariableNames for the collector
236266
func NewVariableLabelNames(upstreamServerVariableLabelNames []string, serverZoneVariableLabelNames []string, upstreamServerPeerVariableLabelNames []string,
237-
streamUpstreamServerVariableLabelNames []string, streamServerZoneLabels []string, streamUpstreamServerPeerVariableLabelNames []string, cacheZoneLabelNames []string,
267+
streamUpstreamServerVariableLabelNames []string, streamServerZoneLabels []string, streamUpstreamServerPeerVariableLabelNames []string, cacheZoneLabelNames []string, workerPIDVariableLabelNames []string,
238268
) VariableLabelNames {
239269
return VariableLabelNames{
240270
UpstreamServerVariableLabelNames: upstreamServerVariableLabelNames,
@@ -244,6 +274,7 @@ func NewVariableLabelNames(upstreamServerVariableLabelNames []string, serverZone
244274
StreamServerZoneVariableLabelNames: streamServerZoneLabels,
245275
StreamUpstreamServerPeerVariableLabelNames: streamUpstreamServerPeerVariableLabelNames,
246276
CacheZoneLabelNames: cacheZoneLabelNames,
277+
WorkerPIDVariableLabelNames: workerPIDVariableLabelNames,
247278
}
248279
}
249280

@@ -543,6 +574,14 @@ func NewNginxPlusCollector(nginxClient *plusclient.NginxClient, namespace string
543574
"bypass_responses_written": newCacheZoneMetric(namespace, "bypass_responses_written", "Total number of cache bypasses written to cache", constLabels),
544575
"bypass_bytes_written": newCacheZoneMetric(namespace, "bypass_bytes_written", "Total number of bytes written to cache from cache bypasses", constLabels),
545576
},
577+
workerMetrics: map[string]*prometheus.Desc{
578+
"connection_accepted": newWorkerMetric(namespace, "connection_accepted", "The total number of accepted client connections", variableLabelNames.WorkerPIDVariableLabelNames, constLabels),
579+
"connection_dropped": newWorkerMetric(namespace, "connection_dropped", "The total number of dropped client connections", variableLabelNames.WorkerPIDVariableLabelNames, constLabels),
580+
"connection_active": newWorkerMetric(namespace, "connection_active", "The current number of active client connections", variableLabelNames.WorkerPIDVariableLabelNames, constLabels),
581+
"connection_idle": newWorkerMetric(namespace, "connection_idle", "The current number of idle client connections", variableLabelNames.WorkerPIDVariableLabelNames, constLabels),
582+
"http_requests_total": newWorkerMetric(namespace, "http_requests_total", "The total number of client requests received by the worker process", variableLabelNames.WorkerPIDVariableLabelNames, constLabels),
583+
"http_requests_current": newWorkerMetric(namespace, "http_requests_current", "The current number of client requests that are currently being processed by the worker process", variableLabelNames.WorkerPIDVariableLabelNames, constLabels),
584+
},
546585
}
547586
}
548587

@@ -593,6 +632,9 @@ func (c *NginxPlusCollector) Describe(ch chan<- *prometheus.Desc) {
593632
for _, m := range c.cacheZoneMetrics {
594633
ch <- m
595634
}
635+
for _, m := range c.workerMetrics {
636+
ch <- m
637+
}
596638
}
597639

598640
// Collect fetches metrics from NGINX Plus and sends them to the provided channel.
@@ -1207,6 +1249,28 @@ func (c *NginxPlusCollector) Collect(ch chan<- prometheus.Metric) {
12071249
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_responses_written"], prometheus.CounterValue, float64(zone.Bypass.ResponsesWritten), name)
12081250
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_bytes_written"], prometheus.CounterValue, float64(zone.Bypass.BytesWritten), name)
12091251
}
1252+
1253+
for _, worker := range stats.Workers {
1254+
labelValues := []string{strconv.FormatInt(int64(worker.ID), 10), strconv.FormatInt(int64(worker.ProcessID), 10)}
1255+
varLabelValues := c.getWorkerLabelValues(strconv.FormatInt(int64(worker.ID), 10))
1256+
1257+
if c.variableLabelNames.WorkerPIDVariableLabelNames != nil && len(varLabelValues) != len(c.variableLabelNames.WorkerPIDVariableLabelNames) {
1258+
level.Warn(c.logger).Log("wrong number of labels for worker %v. For labels %v, got values: %v. Empty labels will be used instead",
1259+
strconv.FormatInt(int64(worker.ID), 10), c.variableLabelNames.WorkerPIDVariableLabelNames, varLabelValues)
1260+
for range c.variableLabelNames.WorkerPIDVariableLabelNames {
1261+
labelValues = append(labelValues, "")
1262+
}
1263+
} else {
1264+
labelValues = append(labelValues, varLabelValues...)
1265+
}
1266+
1267+
ch <- prometheus.MustNewConstMetric(c.workerMetrics["connection_accepted"], prometheus.CounterValue, float64(worker.Connections.Accepted), labelValues...)
1268+
ch <- prometheus.MustNewConstMetric(c.workerMetrics["connection_dropped"], prometheus.CounterValue, float64(worker.Connections.Dropped), labelValues...)
1269+
ch <- prometheus.MustNewConstMetric(c.workerMetrics["connection_active"], prometheus.GaugeValue, float64(worker.Connections.Active), labelValues...)
1270+
ch <- prometheus.MustNewConstMetric(c.workerMetrics["connection_idle"], prometheus.GaugeValue, float64(worker.Connections.Idle), labelValues...)
1271+
ch <- prometheus.MustNewConstMetric(c.workerMetrics["http_requests_total"], prometheus.CounterValue, float64(worker.HTTP.HTTPRequests.Total), labelValues...)
1272+
ch <- prometheus.MustNewConstMetric(c.workerMetrics["http_requests_current"], prometheus.GaugeValue, float64(worker.HTTP.HTTPRequests.Current), labelValues...)
1273+
}
12101274
}
12111275

12121276
var upstreamServerStates = map[string]float64{
@@ -1281,3 +1345,9 @@ func newStreamLimitConnectionMetric(namespace string, metricName string, docStri
12811345
func newCacheZoneMetric(namespace string, metricName string, docString string, constLabels prometheus.Labels) *prometheus.Desc {
12821346
return prometheus.NewDesc(prometheus.BuildFQName(namespace, "cache", metricName), docString, []string{"zone"}, constLabels)
12831347
}
1348+
1349+
func newWorkerMetric(namespace string, metricName string, docString string, variableLabelNames []string, constLabels prometheus.Labels) *prometheus.Desc {
1350+
labels := []string{"id", "pid"}
1351+
labels = append(labels, variableLabelNames...)
1352+
return prometheus.NewDesc(prometheus.BuildFQName(namespace, "worker", metricName), docString, labels, constLabels)
1353+
}

0 commit comments

Comments
 (0)