Skip to content

Commit d57f771

Browse files
authored
add cache metrics for NGINX plus (#540)
Signed-off-by: Mohammad Shehar Yaar Tausif <[email protected]>
1 parent 0edad8e commit d57f771

File tree

3 files changed

+114
-2
lines changed

3 files changed

+114
-2
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,32 @@ Name | Type | Description | Labels
336336
`nginxplus_stream_limit_connection_rejected` | Counter | Total number of connections that were rejected | `zone` |
337337
`nginxplus_stream_limit_connection_rejected_dry_run` | Counter | Total number of connections accounted as rejected in the dry run mode | `zone` |
338338

339+
#### [Cache](https://nginx.org/en/docs/http/ngx_http_api_module.html#http_caches_http_cache_zone_name)
340+
341+
Name | Type | Description | Labels
342+
----|----|----|----
343+
`nginxplus_cache_size` | Gauge | Total size of the cache | `cache`
344+
`nginxplus_cache_max_size` | Gauge | Maximum size of the cache | `cache`
345+
`nginxplus_cache_cold` | Gauge | Is the cache considered cold | `cache`
346+
`nginxplus_cache_hit_responses` | Counter | Total number of cache hits | `cache`
347+
`nginxplus_cache_hit_bytes` | Counter | Total number of bytes returned from cache hits | `cache`
348+
`nginxplus_cache_stale_responses` | Counter | Total number of stale cache hits | `cache`
349+
`nginxplus_cache_stale_bytes` | Counter | Total number of bytes returned from stale cache hits | `cache`
350+
`nginxplus_cache_updating_responses` | Counter | Total number of cache hits while cache is updating | `cache`
351+
`nginxplus_cache_updating_bytes` | Counter | Total number of bytes returned from cache while cache is updating | `cache`
352+
`nginxplus_cache_revalidated_responses` | Counter | Total number of cache revalidations | `cache`
353+
`nginxplus_cache_revalidated_bytes` | Counter | Total number of bytes returned from cache revalidations | `cache`
354+
`nginxplus_cache_miss_responses` | Counter | Total number of cache misses | `cache`
355+
`nginxplus_cache_miss_bytes` | Counter | Total number of bytes returned from cache misses | `cache`
356+
`nginxplus_cache_expired_responses` | Counter | Total number of cache hits with expired TTL | `cache`
357+
`nginxplus_cache_expired_bytes` | Counter | Total number of bytes returned from cache hits with expired TTL | `cache`
358+
`nginxplus_cache_expired_responses_written` | Counter | Total number of cache hits with expired TTL written to cache | `cache`
359+
`nginxplus_cache_expired_bytes_written` | Counter | Total number of bytes written to cache from cache hits with expired TTL | `cache`
360+
`nginxplus_cache_bypass_responses` | Counter | Total number of cache bypasses | `cache`
361+
`nginxplus_cache_bypass_bytes` | Counter | Total number of bytes returned from cache bypasses | `cache`
362+
`nginxplus_cache_bypass_responses_written` | Counter | Total number of cache bypasses written to cache | `cache`
363+
`nginxplus_cache_bypass_bytes_written` | Counter | Total number of bytes written to cache from cache bypasses | `cache`
364+
339365
Connect to the `/metrics` page of the running exporter to see the complete list of metrics along with their
340366
descriptions. Note: to see server zones related metrics you must configure [status
341367
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: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ type LabelUpdater interface {
2424
DeleteServerZoneLabels(zoneNames []string)
2525
UpdateStreamServerZoneLabels(streamServerZoneLabelValues map[string][]string)
2626
DeleteStreamServerZoneLabels(zoneNames []string)
27+
UpdateCacheZoneLabels(cacheLabelValues map[string][]string)
28+
DeleteCacheZoneLabels(cacheNames []string)
2729
}
2830

2931
// NginxPlusCollector collects NGINX Plus metrics. It implements prometheus.Collector interface.
@@ -42,6 +44,7 @@ type NginxPlusCollector struct {
4244
limitRequestMetrics map[string]*prometheus.Desc
4345
limitConnectionMetrics map[string]*prometheus.Desc
4446
streamLimitConnectionMetrics map[string]*prometheus.Desc
47+
cacheZoneMetrics map[string]*prometheus.Desc
4548
upMetric prometheus.Gauge
4649
mutex sync.Mutex
4750
variableLabelNames VariableLabelNames
@@ -51,6 +54,7 @@ type NginxPlusCollector struct {
5154
streamServerZoneLabels map[string][]string
5255
upstreamServerPeerLabels map[string][]string
5356
streamUpstreamServerPeerLabels map[string][]string
57+
cacheZoneLabels map[string][]string
5458
variableLabelsMutex sync.RWMutex
5559
logger log.Logger
5660
}
@@ -163,6 +167,24 @@ func (c *NginxPlusCollector) DeleteStreamServerZoneLabels(zoneNames []string) {
163167
c.variableLabelsMutex.Unlock()
164168
}
165169

170+
// UpdateCacheZoneLabels updates the Upstream Cache Zone labels
171+
func (c *NginxPlusCollector) UpdateCacheZoneLabels(cacheZoneLabelValues map[string][]string) {
172+
c.variableLabelsMutex.Lock()
173+
for k, v := range cacheZoneLabelValues {
174+
c.cacheZoneLabels[k] = v
175+
}
176+
c.variableLabelsMutex.Unlock()
177+
}
178+
179+
// DeleteCacheZoneLabels deletes the Cache Zone Labels
180+
func (c *NginxPlusCollector) DeleteCacheZoneLabels(cacheZoneNames []string) {
181+
c.variableLabelsMutex.Lock()
182+
for _, k := range cacheZoneNames {
183+
delete(c.cacheZoneLabels, k)
184+
}
185+
c.variableLabelsMutex.Unlock()
186+
}
187+
166188
func (c *NginxPlusCollector) getUpstreamServerLabelValues(upstreamName string) []string {
167189
c.variableLabelsMutex.RLock()
168190
defer c.variableLabelsMutex.RUnlock()
@@ -207,11 +229,12 @@ type VariableLabelNames struct {
207229
StreamUpstreamServerPeerVariableLabelNames []string
208230
StreamServerZoneVariableLabelNames []string
209231
StreamUpstreamServerVariableLabelNames []string
232+
CacheZoneLabelNames []string
210233
}
211234

212235
// NewVariableLabels creates a new struct for VariableNames for the collector
213236
func NewVariableLabelNames(upstreamServerVariableLabelNames []string, serverZoneVariableLabelNames []string, upstreamServerPeerVariableLabelNames []string,
214-
streamUpstreamServerVariableLabelNames []string, streamServerZoneLabels []string, streamUpstreamServerPeerVariableLabelNames []string,
237+
streamUpstreamServerVariableLabelNames []string, streamServerZoneLabels []string, streamUpstreamServerPeerVariableLabelNames []string, cacheZoneLabelNames []string,
215238
) VariableLabelNames {
216239
return VariableLabelNames{
217240
UpstreamServerVariableLabelNames: upstreamServerVariableLabelNames,
@@ -220,6 +243,7 @@ func NewVariableLabelNames(upstreamServerVariableLabelNames []string, serverZone
220243
StreamUpstreamServerVariableLabelNames: streamUpstreamServerVariableLabelNames,
221244
StreamServerZoneVariableLabelNames: streamServerZoneLabels,
222245
StreamUpstreamServerPeerVariableLabelNames: streamUpstreamServerPeerVariableLabelNames,
246+
CacheZoneLabelNames: cacheZoneLabelNames,
223247
}
224248
}
225249

@@ -496,6 +520,29 @@ func NewNginxPlusCollector(nginxClient *plusclient.NginxClient, namespace string
496520
"rejected_dry_run": newStreamLimitConnectionMetric(namespace, "rejected_dry_run", "Total number of connections accounted as rejected in the dry run mode", constLabels),
497521
},
498522
upMetric: newUpMetric(namespace, constLabels),
523+
cacheZoneMetrics: map[string]*prometheus.Desc{
524+
"size": newCacheZoneMetric(namespace, "size", "Total size of the cache", constLabels),
525+
"max_size": newCacheZoneMetric(namespace, "max_size", "Maximum size of the cache", constLabels),
526+
"cold": newCacheZoneMetric(namespace, "cold", "Is the cache considered cold", constLabels),
527+
"hit_responses": newCacheZoneMetric(namespace, "hit_responses", "Total number of cache hits", constLabels),
528+
"hit_bytes": newCacheZoneMetric(namespace, "hit_bytes", "Total number of bytes returned from cache", constLabels),
529+
"stale_responses": newCacheZoneMetric(namespace, "stale_responses", "Total number of stale cache hits", constLabels),
530+
"stale_bytes": newCacheZoneMetric(namespace, "stale_bytes", "Total number of bytes returned from stale cache", constLabels),
531+
"updating_responses": newCacheZoneMetric(namespace, "updating_responses", "Total number of cache hits while cache is updating", constLabels),
532+
"updating_bytes": newCacheZoneMetric(namespace, "updating_bytes", "Total number of bytes returned from cache while cache is updating", constLabels),
533+
"revalidated_responses": newCacheZoneMetric(namespace, "revalidated_responses", "Total number of cache revalidations", constLabels),
534+
"revalidated_bytes": newCacheZoneMetric(namespace, "revalidated_bytes", "Total number of bytes returned from cache revalidations", constLabels),
535+
"miss_responses": newCacheZoneMetric(namespace, "miss_responses", "Total number of cache misses", constLabels),
536+
"miss_bytes": newCacheZoneMetric(namespace, "miss_bytes", "Total number of bytes returned from cache misses", constLabels),
537+
"expired_responses": newCacheZoneMetric(namespace, "expired_responses", "Total number of cache hits with expired TTL", constLabels),
538+
"expired_bytes": newCacheZoneMetric(namespace, "expired_bytes", "Total number of bytes returned from cache hits with expired TTL", constLabels),
539+
"expired_responses_written": newCacheZoneMetric(namespace, "expired_responses_written", "Total number of cache hits with expired TTL written to cache", constLabels),
540+
"expired_bytes_written": newCacheZoneMetric(namespace, "expired_bytes_written", "Total number of bytes written to cache from cache hits with expired TTL", constLabels),
541+
"bypass_responses": newCacheZoneMetric(namespace, "bypass_responses", "Total number of cache bypasses", constLabels),
542+
"bypass_bytes": newCacheZoneMetric(namespace, "bypass_bytes", "Total number of bytes returned from cache bypasses", constLabels),
543+
"bypass_responses_written": newCacheZoneMetric(namespace, "bypass_responses_written", "Total number of cache bypasses written to cache", constLabels),
544+
"bypass_bytes_written": newCacheZoneMetric(namespace, "bypass_bytes_written", "Total number of bytes written to cache from cache bypasses", constLabels),
545+
},
499546
}
500547
}
501548

@@ -543,6 +590,9 @@ func (c *NginxPlusCollector) Describe(ch chan<- *prometheus.Desc) {
543590
for _, m := range c.streamLimitConnectionMetrics {
544591
ch <- m
545592
}
593+
for _, m := range c.cacheZoneMetrics {
594+
ch <- m
595+
}
546596
}
547597

548598
// Collect fetches metrics from NGINX Plus and sends them to the provided channel.
@@ -1125,6 +1175,38 @@ func (c *NginxPlusCollector) Collect(ch chan<- prometheus.Metric) {
11251175
ch <- prometheus.MustNewConstMetric(c.streamLimitConnectionMetrics["rejected"], prometheus.CounterValue, float64(zone.Rejected), name)
11261176
ch <- prometheus.MustNewConstMetric(c.streamLimitConnectionMetrics["rejected_dry_run"], prometheus.CounterValue, float64(zone.RejectedDryRun), name)
11271177
}
1178+
1179+
for name, zone := range stats.Caches {
1180+
1181+
var cold float64
1182+
if zone.Cold {
1183+
cold = 1.0
1184+
} else {
1185+
cold = 0.0
1186+
}
1187+
1188+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["size"], prometheus.GaugeValue, float64(zone.Size), name)
1189+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["max_size"], prometheus.GaugeValue, float64(zone.MaxSize), name)
1190+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["cold"], prometheus.GaugeValue, cold, name)
1191+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["hit_responses"], prometheus.CounterValue, float64(zone.Hit.Responses), name)
1192+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["hit_bytes"], prometheus.CounterValue, float64(zone.Hit.Bytes), name)
1193+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["stale_responses"], prometheus.CounterValue, float64(zone.Stale.Responses), name)
1194+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["stale_bytes"], prometheus.CounterValue, float64(zone.Stale.Bytes), name)
1195+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["updating_responses"], prometheus.CounterValue, float64(zone.Updating.Responses), name)
1196+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["updating_bytes"], prometheus.CounterValue, float64(zone.Updating.Bytes), name)
1197+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["revalidated_responses"], prometheus.CounterValue, float64(zone.Revalidated.Responses), name)
1198+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["revalidated_bytes"], prometheus.CounterValue, float64(zone.Revalidated.Bytes), name)
1199+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["miss_responses"], prometheus.CounterValue, float64(zone.Miss.Responses), name)
1200+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["miss_bytes"], prometheus.CounterValue, float64(zone.Miss.Bytes), name)
1201+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_responses"], prometheus.CounterValue, float64(zone.Expired.Responses), name)
1202+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_bytes"], prometheus.CounterValue, float64(zone.Expired.Bytes), name)
1203+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_responses_written"], prometheus.CounterValue, float64(zone.Expired.ResponsesWritten), name)
1204+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_bytes_written"], prometheus.CounterValue, float64(zone.Expired.BytesWritten), name)
1205+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_responses"], prometheus.CounterValue, float64(zone.Bypass.Responses), name)
1206+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_bytes"], prometheus.CounterValue, float64(zone.Bypass.Bytes), name)
1207+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_responses_written"], prometheus.CounterValue, float64(zone.Bypass.ResponsesWritten), name)
1208+
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_bytes_written"], prometheus.CounterValue, float64(zone.Bypass.BytesWritten), name)
1209+
}
11281210
}
11291211

11301212
var upstreamServerStates = map[string]float64{
@@ -1195,3 +1277,7 @@ func newLimitConnectionMetric(namespace string, metricName string, docString str
11951277
func newStreamLimitConnectionMetric(namespace string, metricName string, docString string, constLabels prometheus.Labels) *prometheus.Desc {
11961278
return prometheus.NewDesc(prometheus.BuildFQName(namespace, "stream_limit_connection", metricName), docString, []string{"zone"}, constLabels)
11971279
}
1280+
1281+
func newCacheZoneMetric(namespace string, metricName string, docString string, constLabels prometheus.Labels) *prometheus.Desc {
1282+
return prometheus.NewDesc(prometheus.BuildFQName(namespace, "cache", metricName), docString, []string{"zone"}, constLabels)
1283+
}

exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func main() {
180180
level.Error(logger).Log("msg", "Could not create Nginx Plus Client", "error", err.Error())
181181
os.Exit(1)
182182
}
183-
variableLabelNames := collector.NewVariableLabelNames(nil, nil, nil, nil, nil, nil)
183+
variableLabelNames := collector.NewVariableLabelNames(nil, nil, nil, nil, nil, nil, nil)
184184
prometheus.MustRegister(collector.NewNginxPlusCollector(plusClient, "nginxplus", variableLabelNames, constLabels, logger))
185185
} else {
186186
ossClient := client.NewNginxClient(httpClient, *scrapeURI)

0 commit comments

Comments
 (0)