Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,32 @@ Name | Type | Description | Labels
`nginxplus_stream_limit_connection_rejected` | Counter | Total number of connections that were rejected | `zone` |
`nginxplus_stream_limit_connection_rejected_dry_run` | Counter | Total number of connections accounted as rejected in the dry run mode | `zone` |

#### [Cache](https://nginx.org/en/docs/http/ngx_http_api_module.html#http_caches_http_cache_zone_name)

Name | Type | Description | Labels
----|----|----|----
`nginxplus_cache_size` | Gauge | Total size of the cache | `cache`
`nginxplus_cache_max_size` | Gauge | Maximum size of the cache | `cache`
`nginxplus_cache_cold` | Gauge | Is the cache considered cold | `cache`
`nginxplus_cache_hit_responses` | Counter | Total number of cache hits | `cache`
`nginxplus_cache_hit_bytes` | Counter | Total number of bytes returned from cache hits | `cache`
`nginxplus_cache_stale_responses` | Counter | Total number of stale cache hits | `cache`
`nginxplus_cache_stale_bytes` | Counter | Total number of bytes returned from stale cache hits | `cache`
`nginxplus_cache_updating_responses` | Counter | Total number of cache hits while cache is updating | `cache`
`nginxplus_cache_updating_bytes` | Counter | Total number of bytes returned from cache while cache is updating | `cache`
`nginxplus_cache_revalidated_responses` | Counter | Total number of cache revalidations | `cache`
`nginxplus_cache_revalidated_bytes` | Counter | Total number of bytes returned from cache revalidations | `cache`
`nginxplus_cache_miss_responses` | Counter | Total number of cache misses | `cache`
`nginxplus_cache_miss_bytes` | Counter | Total number of bytes returned from cache misses | `cache`
`nginxplus_cache_expired_responses` | Counter | Total number of cache hits with expired TTL | `cache`
`nginxplus_cache_expired_bytes` | Counter | Total number of bytes returned from cache hits with expired TTL | `cache`
`nginxplus_cache_expired_responses_written` | Counter | Total number of cache hits with expired TTL written to cache | `cache`
`nginxplus_cache_expired_bytes_written` | Counter | Total number of bytes written to cache from cache hits with expired TTL | `cache`
`nginxplus_cache_bypass_responses` | Counter | Total number of cache bypasses | `cache`
`nginxplus_cache_bypass_bytes` | Counter | Total number of bytes returned from cache bypasses | `cache`
`nginxplus_cache_bypass_responses_written` | Counter | Total number of cache bypasses written to cache | `cache`
`nginxplus_cache_bypass_bytes_written` | Counter | Total number of bytes written to cache from cache bypasses | `cache`

Connect to the `/metrics` page of the running exporter to see the complete list of metrics along with their
descriptions. Note: to see server zones related metrics you must configure [status
zones](https://nginx.org/en/docs/http/ngx_http_status_module.html#status_zone) and to see upstream related metrics you
Expand Down
88 changes: 87 additions & 1 deletion collector/nginx_plus.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type LabelUpdater interface {
DeleteServerZoneLabels(zoneNames []string)
UpdateStreamServerZoneLabels(streamServerZoneLabelValues map[string][]string)
DeleteStreamServerZoneLabels(zoneNames []string)
UpdateCacheZoneLabels(cacheLabelValues map[string][]string)
DeleteCacheZoneLabels(cacheNames []string)
}

// NginxPlusCollector collects NGINX Plus metrics. It implements prometheus.Collector interface.
Expand All @@ -42,6 +44,7 @@ type NginxPlusCollector struct {
limitRequestMetrics map[string]*prometheus.Desc
limitConnectionMetrics map[string]*prometheus.Desc
streamLimitConnectionMetrics map[string]*prometheus.Desc
cacheZoneMetrics map[string]*prometheus.Desc
upMetric prometheus.Gauge
mutex sync.Mutex
variableLabelNames VariableLabelNames
Expand All @@ -51,6 +54,7 @@ type NginxPlusCollector struct {
streamServerZoneLabels map[string][]string
upstreamServerPeerLabels map[string][]string
streamUpstreamServerPeerLabels map[string][]string
cacheZoneLabels map[string][]string
variableLabelsMutex sync.RWMutex
logger log.Logger
}
Expand Down Expand Up @@ -163,6 +167,24 @@ func (c *NginxPlusCollector) DeleteStreamServerZoneLabels(zoneNames []string) {
c.variableLabelsMutex.Unlock()
}

// UpdateCacheZoneLabels updates the Upstream Cache Zone labels
func (c *NginxPlusCollector) UpdateCacheZoneLabels(cacheZoneLabelValues map[string][]string) {
c.variableLabelsMutex.Lock()
for k, v := range cacheZoneLabelValues {
c.cacheZoneLabels[k] = v
}
c.variableLabelsMutex.Unlock()
}

// DeleteCacheZoneLabels deletes the Cache Zone Labels
func (c *NginxPlusCollector) DeleteCacheZoneLabels(cacheZoneNames []string) {
c.variableLabelsMutex.Lock()
for _, k := range cacheZoneNames {
delete(c.cacheZoneLabels, k)
}
c.variableLabelsMutex.Unlock()
}

func (c *NginxPlusCollector) getUpstreamServerLabelValues(upstreamName string) []string {
c.variableLabelsMutex.RLock()
defer c.variableLabelsMutex.RUnlock()
Expand Down Expand Up @@ -207,11 +229,12 @@ type VariableLabelNames struct {
StreamUpstreamServerPeerVariableLabelNames []string
StreamServerZoneVariableLabelNames []string
StreamUpstreamServerVariableLabelNames []string
CacheZoneLabelNames []string
}

// NewVariableLabels creates a new struct for VariableNames for the collector
func NewVariableLabelNames(upstreamServerVariableLabelNames []string, serverZoneVariableLabelNames []string, upstreamServerPeerVariableLabelNames []string,
streamUpstreamServerVariableLabelNames []string, streamServerZoneLabels []string, streamUpstreamServerPeerVariableLabelNames []string,
streamUpstreamServerVariableLabelNames []string, streamServerZoneLabels []string, streamUpstreamServerPeerVariableLabelNames []string, cacheZoneLabelNames []string,
) VariableLabelNames {
return VariableLabelNames{
UpstreamServerVariableLabelNames: upstreamServerVariableLabelNames,
Expand All @@ -220,6 +243,7 @@ func NewVariableLabelNames(upstreamServerVariableLabelNames []string, serverZone
StreamUpstreamServerVariableLabelNames: streamUpstreamServerVariableLabelNames,
StreamServerZoneVariableLabelNames: streamServerZoneLabels,
StreamUpstreamServerPeerVariableLabelNames: streamUpstreamServerPeerVariableLabelNames,
CacheZoneLabelNames: cacheZoneLabelNames,
}
}

Expand Down Expand Up @@ -496,6 +520,29 @@ func NewNginxPlusCollector(nginxClient *plusclient.NginxClient, namespace string
"rejected_dry_run": newStreamLimitConnectionMetric(namespace, "rejected_dry_run", "Total number of connections accounted as rejected in the dry run mode", constLabels),
},
upMetric: newUpMetric(namespace, constLabels),
cacheZoneMetrics: map[string]*prometheus.Desc{
"size": newCacheZoneMetric(namespace, "size", "Total size of the cache", constLabels),
"max_size": newCacheZoneMetric(namespace, "max_size", "Maximum size of the cache", constLabels),
"cold": newCacheZoneMetric(namespace, "cold", "Is the cache considered cold", constLabels),
"hit_responses": newCacheZoneMetric(namespace, "hit_responses", "Total number of cache hits", constLabels),
"hit_bytes": newCacheZoneMetric(namespace, "hit_bytes", "Total number of bytes returned from cache", constLabels),
"stale_responses": newCacheZoneMetric(namespace, "stale_responses", "Total number of stale cache hits", constLabels),
"stale_bytes": newCacheZoneMetric(namespace, "stale_bytes", "Total number of bytes returned from stale cache", constLabels),
"updating_responses": newCacheZoneMetric(namespace, "updating_responses", "Total number of cache hits while cache is updating", constLabels),
"updating_bytes": newCacheZoneMetric(namespace, "updating_bytes", "Total number of bytes returned from cache while cache is updating", constLabels),
"revalidated_responses": newCacheZoneMetric(namespace, "revalidated_responses", "Total number of cache revalidations", constLabels),
"revalidated_bytes": newCacheZoneMetric(namespace, "revalidated_bytes", "Total number of bytes returned from cache revalidations", constLabels),
"miss_responses": newCacheZoneMetric(namespace, "miss_responses", "Total number of cache misses", constLabels),
"miss_bytes": newCacheZoneMetric(namespace, "miss_bytes", "Total number of bytes returned from cache misses", constLabels),
"expired_responses": newCacheZoneMetric(namespace, "expired_responses", "Total number of cache hits with expired TTL", constLabels),
"expired_bytes": newCacheZoneMetric(namespace, "expired_bytes", "Total number of bytes returned from cache hits with expired TTL", constLabels),
"expired_responses_written": newCacheZoneMetric(namespace, "expired_responses_written", "Total number of cache hits with expired TTL written to cache", constLabels),
"expired_bytes_written": newCacheZoneMetric(namespace, "expired_bytes_written", "Total number of bytes written to cache from cache hits with expired TTL", constLabels),
"bypass_responses": newCacheZoneMetric(namespace, "bypass_responses", "Total number of cache bypasses", constLabels),
"bypass_bytes": newCacheZoneMetric(namespace, "bypass_bytes", "Total number of bytes returned from cache bypasses", constLabels),
"bypass_responses_written": newCacheZoneMetric(namespace, "bypass_responses_written", "Total number of cache bypasses written to cache", constLabels),
"bypass_bytes_written": newCacheZoneMetric(namespace, "bypass_bytes_written", "Total number of bytes written to cache from cache bypasses", constLabels),
},
}
}

Expand Down Expand Up @@ -543,6 +590,9 @@ func (c *NginxPlusCollector) Describe(ch chan<- *prometheus.Desc) {
for _, m := range c.streamLimitConnectionMetrics {
ch <- m
}
for _, m := range c.cacheZoneMetrics {
ch <- m
}
}

// Collect fetches metrics from NGINX Plus and sends them to the provided channel.
Expand Down Expand Up @@ -1125,6 +1175,38 @@ func (c *NginxPlusCollector) Collect(ch chan<- prometheus.Metric) {
ch <- prometheus.MustNewConstMetric(c.streamLimitConnectionMetrics["rejected"], prometheus.CounterValue, float64(zone.Rejected), name)
ch <- prometheus.MustNewConstMetric(c.streamLimitConnectionMetrics["rejected_dry_run"], prometheus.CounterValue, float64(zone.RejectedDryRun), name)
}

for name, zone := range stats.Caches {

var cold float64
if zone.Cold {
cold = 1.0
} else {
cold = 0.0
}

ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["size"], prometheus.GaugeValue, float64(zone.Size), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["max_size"], prometheus.GaugeValue, float64(zone.MaxSize), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["cold"], prometheus.GaugeValue, cold, name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["hit_responses"], prometheus.CounterValue, float64(zone.Hit.Responses), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["hit_bytes"], prometheus.CounterValue, float64(zone.Hit.Bytes), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["stale_responses"], prometheus.CounterValue, float64(zone.Stale.Responses), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["stale_bytes"], prometheus.CounterValue, float64(zone.Stale.Bytes), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["updating_responses"], prometheus.CounterValue, float64(zone.Updating.Responses), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["updating_bytes"], prometheus.CounterValue, float64(zone.Updating.Bytes), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["revalidated_responses"], prometheus.CounterValue, float64(zone.Revalidated.Responses), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["revalidated_bytes"], prometheus.CounterValue, float64(zone.Revalidated.Bytes), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["miss_responses"], prometheus.CounterValue, float64(zone.Miss.Responses), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["miss_bytes"], prometheus.CounterValue, float64(zone.Miss.Bytes), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_responses"], prometheus.CounterValue, float64(zone.Expired.Responses), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_bytes"], prometheus.CounterValue, float64(zone.Expired.Bytes), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_responses_written"], prometheus.CounterValue, float64(zone.Expired.ResponsesWritten), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["expired_bytes_written"], prometheus.CounterValue, float64(zone.Expired.BytesWritten), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_responses"], prometheus.CounterValue, float64(zone.Bypass.Responses), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_bytes"], prometheus.CounterValue, float64(zone.Bypass.Bytes), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_responses_written"], prometheus.CounterValue, float64(zone.Bypass.ResponsesWritten), name)
ch <- prometheus.MustNewConstMetric(c.cacheZoneMetrics["bypass_bytes_written"], prometheus.CounterValue, float64(zone.Bypass.BytesWritten), name)
}
}

var upstreamServerStates = map[string]float64{
Expand Down Expand Up @@ -1195,3 +1277,7 @@ func newLimitConnectionMetric(namespace string, metricName string, docString str
func newStreamLimitConnectionMetric(namespace string, metricName string, docString string, constLabels prometheus.Labels) *prometheus.Desc {
return prometheus.NewDesc(prometheus.BuildFQName(namespace, "stream_limit_connection", metricName), docString, []string{"zone"}, constLabels)
}

func newCacheZoneMetric(namespace string, metricName string, docString string, constLabels prometheus.Labels) *prometheus.Desc {
return prometheus.NewDesc(prometheus.BuildFQName(namespace, "cache", metricName), docString, []string{"zone"}, constLabels)
}
2 changes: 1 addition & 1 deletion exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func main() {
level.Error(logger).Log("msg", "Could not create Nginx Plus Client", "error", err.Error())
os.Exit(1)
}
variableLabelNames := collector.NewVariableLabelNames(nil, nil, nil, nil, nil, nil)
variableLabelNames := collector.NewVariableLabelNames(nil, nil, nil, nil, nil, nil, nil)
prometheus.MustRegister(collector.NewNginxPlusCollector(plusClient, "nginxplus", variableLabelNames, constLabels, logger))
} else {
ossClient := client.NewNginxClient(httpClient, *scrapeURI)
Expand Down