
# NGINX Plus by HTTP

## Overview

This template is designed for the effortless deployment of Nginx Plus monitoring by Zabbix via HTTP and doesn't require any external scripts.

> The monitoring data of the live activity is generated by the [NGINX Plus API](http://nginx.org/en/docs/http/ngx_http_api_module.html).

## Requirements

Zabbix version: 7.4 and higher.

## Tested versions

This template has been tested on:
- NGINX Plus 1.19.10

## Configuration

> Zabbix should be configured according to the instructions in the [Templates out of the box](https://www.zabbix.com/documentation/7.4/manual/config/templates_out_of_the_box) section.

## Setup

1. Enable the NGINX Plus API.
> Refer to the [vendor documentation](https://www.nginx.com/products/nginx/live-activity-monitoring/).
2. Set the {$NGINX.API.ENDPOINT} such as `<scheme>://<host>:<port>/<location>/`.

**Note** that depending on the number of zones and upstreams discovery operation may be expensive. 
Therefore, use the following filters with these macros:

- {$NGINX.LLD.FILTER.HTTP.ZONE.MATCHES}
- {$NGINX.LLD.FILTER.HTTP.ZONE.NOT_MATCHES}
- {$NGINX.LLD.FILTER.HTTP.LOCATION.ZONE.MATCHES}
- {$NGINX.LLD.FILTER.HTTP.LOCATION.ZONE.NOT_MATCHES}
- {$NGINX.LLD.FILTER.HTTP.UPSTREAM.MATCHES}
- {$NGINX.LLD.FILTER.HTTP.UPSTREAM.NOT_MATCHES}
- {$NGINX.LLD.FILTER.STREAM.ZONE.MATCHES}
- {$NGINX.LLD.FILTER.STREAM.ZONE.NOT_MATCHES}
- {$NGINX.LLD.FILTER.STREAM.UPSTREAM.MATCHES}
- {$NGINX.LLD.FILTER.STREAM.UPSTREAM.NOT_MATCHES}
- {$NGINX.LLD.FILTER.RESOLVER.MATCHES}
- {$NGINX.LLD.FILTER.RESOLVER.NOT_MATCHES}

### Macros used

|Name|Description|Default|
|----|-----------|-------|
|{$NGINX.API.ENDPOINT}|<p>NGINX Plus API URL in the format `<scheme>://<host>:<port>/<location>/`.</p>||
|{$NGINX.LLD.FILTER.HTTP.ZONE.MATCHES}|<p>The filter to include the necessary discovered HTTP server zones.</p>|`.*`|
|{$NGINX.LLD.FILTER.HTTP.ZONE.NOT_MATCHES}|<p>The filter to exclude discovered HTTP server zones.</p>|`CHANGE_IF_NEEDED`|
|{$NGINX.LLD.FILTER.HTTP.LOCATION.ZONE.MATCHES}|<p>The filter to include the necessary discovered HTTP location zones.</p>|`.*`|
|{$NGINX.LLD.FILTER.HTTP.LOCATION.ZONE.NOT_MATCHES}|<p>The filter to exclude discovered HTTP location zones.</p>|`CHANGE_IF_NEEDED`|
|{$NGINX.LLD.FILTER.HTTP.UPSTREAM.MATCHES}|<p>The filter to include the necessary discovered HTTP upstreams.</p>|`.*`|
|{$NGINX.LLD.FILTER.HTTP.UPSTREAM.NOT_MATCHES}|<p>The filter to exclude discovered HTTP upstreams.</p>|`CHANGE_IF_NEEDED`|
|{$NGINX.LLD.FILTER.STREAM.ZONE.MATCHES}|<p>The filter to include discovered server zones of the "stream" directive.</p>|`.*`|
|{$NGINX.LLD.FILTER.STREAM.ZONE.NOT_MATCHES}|<p>The filter to exclude discovered server zones of the "stream" directive.</p>|`CHANGE_IF_NEEDED`|
|{$NGINX.LLD.FILTER.STREAM.UPSTREAM.MATCHES}|<p>The filter to include the necessary discovered upstreams of the "stream" directive.</p>|`.*`|
|{$NGINX.LLD.FILTER.STREAM.UPSTREAM.NOT_MATCHES}|<p>The filter to exclude discovered upstreams of the "stream" directive</p>|`CHANGE_IF_NEEDED`|
|{$NGINX.LLD.FILTER.RESOLVER.MATCHES}|<p>The filter to include the necessary discovered `Resolvers`.</p>|`.*`|
|{$NGINX.LLD.FILTER.RESOLVER.NOT_MATCHES}|<p>The filter to exclude discovered `Resolvers`.</p>|`CHANGE_IF_NEEDED`|
|{$NGINX.DROP_RATE.MAX.WARN}|<p>The critical rate of the dropped connections for a  trigger expression.</p>|`1`|
|{$NGINX.HTTP.UPSTREAM.4XX.MAX.WARN}|<p>The maximum percentage of errors with the status code `4xx` (for a trigger expression).</p>|`5`|
|{$NGINX.HTTP.UPSTREAM.5XX.MAX.WARN}|<p>The maximum percentage of errors with the status code `5xx` (for a trigger expression).</p>|`5`|

### Items

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Get info|<p>Return status of the NGINX running instance.</p>|HTTP agent|nginx.info|
|Get connections|<p>Returns the statistics of client connections.</p>|HTTP agent|nginx.connections|
|Get SSL|<p>Returns the SSL statistics.</p>|HTTP agent|nginx.ssl|
|Get requests|<p>Returns the status of the client's HTTP requests.</p>|HTTP agent|nginx.requests|
|Get HTTP zones|<p>Returns the status information for each HTTP server zone.</p>|HTTP agent|nginx.http.server_zones|
|Get HTTP location zones|<p>Returns the status information for each HTTP location zone.</p>|HTTP agent|nginx.http.location_zones|
|Get HTTP upstreams|<p>Returns the status of each HTTP upstream server group and its servers.</p>|HTTP agent|nginx.http.upstreams|
|Get Stream server zones|<p>Returns the status information for each server zone configured in the "stream" directive.</p>|HTTP agent|nginx.stream.server_zones|
|Get Stream upstreams|<p>Returns status of each stream upstream server group and its servers.</p>|HTTP agent|nginx.stream.upstreams|
|Get resolvers|<p>Returns the status information for each Resolver zone.</p>|HTTP agent|nginx.resolvers|
|Get info error|<p>The description of NGINX errors.</p>|Dependent item|nginx.info.error<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.error.text`</p><p>⛔️Custom on fail: Set value to: ``</p></li><li><p>Discard unchanged with heartbeat: `1h`</p></li></ul>|
|Version|<p>A version number of NGINX.</p>|Dependent item|nginx.info.version<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.version`</p></li><li><p>Discard unchanged with heartbeat: `3h`</p></li></ul>|
|Address|<p>The address of the server that accepted status request.</p>|Dependent item|nginx.info.address<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.address`</p></li><li><p>Discard unchanged with heartbeat: `3h`</p></li></ul>|
|Generation|<p>The total number of configuration reloads.</p>|Dependent item|nginx.info.generation<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.generation`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|
|Uptime|<p>The server uptime.</p>|Dependent item|nginx.info.uptime<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.load_timestamp`</p><p>⛔️Custom on fail: Discard value</p></li><li><p>JavaScript: `The text is too long. Please see the template.`</p></li></ul>|
|Connections accepted, rate|<p>The total number of accepted client connections per second.</p>|Dependent item|nginx.connections.accepted.rate<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.accepted`</p></li><li>Change per second</li></ul>|
|Connections dropped|<p>The total number of dropped client connections.</p>|Dependent item|nginx.connections.dropped<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.dropped`</p></li></ul>|
|Connections active|<p>The current number of active client connections.</p>|Dependent item|nginx.connections.active<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.active`</p></li></ul>|
|Connections idle|<p>The current number of idle client connections.</p>|Dependent item|nginx.connections.idle<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.idle`</p></li></ul>|
|SSL handshakes, rate|<p>The total number of successful SSL handshakes per second.</p>|Dependent item|nginx.ssl.handshakes.rate<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.handshakes`</p></li><li>Change per second</li></ul>|
|SSL handshakes failed, rate|<p>The total number of failed SSL handshakes per second.</p>|Dependent item|nginx.ssl.handshakes_failed.rate<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.handshakes_failed`</p></li><li>Change per second</li></ul>|
|SSL session reuses, rate|<p>The total number of session reuses during SSL handshake per second.</p>|Dependent item|nginx.ssl.session_reuses.rate<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.session_reuses`</p></li><li>Change per second</li></ul>|
|Requests total, rate|<p>The total number of client requests per second.</p>|Dependent item|nginx.requests.total.rate<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.total`</p></li><li>Change per second</li></ul>|
|Requests current|<p>The current number of client requests.</p>|Dependent item|nginx.requests.current<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.current`</p></li></ul>|

### Triggers

|Name|Description|Expression|Severity|Dependencies and additional info|
|----|-----------|----------|--------|--------------------------------|
|NGINX Plus: Server response error||`length(last(/NGINX Plus by HTTP/nginx.info.error))>0`|High||
|NGINX Plus: Version has changed|<p>The Nginx version has changed. Acknowledge to close the problem manually.</p>|`last(/NGINX Plus by HTTP/nginx.info.version,#1)<>last(/NGINX Plus by HTTP/nginx.info.version,#2) and length(last(/NGINX Plus by HTTP/nginx.info.version))>0`|Info|**Manual close**: Yes|
|NGINX Plus: Host has been restarted|<p>Uptime is less than 10 minutes.</p>|`last(/NGINX Plus by HTTP/nginx.info.uptime)<10m`|Info|**Manual close**: Yes|
|NGINX Plus: Failed to fetch info data|<p>Zabbix has not received any data for metrics for the last 30 minutes</p>|`nodata(/NGINX Plus by HTTP/nginx.info.uptime,30m)=1`|Warning|**Manual close**: Yes|
|NGINX Plus: High connections drop rate|<p>The rate of dropped connections is greater than `{$NGINX.DROP_RATE.MAX.WARN}` for the last 5 minutes.</p>|`min(/NGINX Plus by HTTP/nginx.connections.dropped,5m) > {$NGINX.DROP_RATE.MAX.WARN}`|Warning||

### LLD rule HTTP server zones discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP server zones discovery||Dependent item|nginx.http.server_zones.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for HTTP server zones discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP server zone [{#NAME}]: Raw data|<p>The raw data of the HTTP server zone with the name `{#NAME}` .</p>|Dependent item|nginx.http.server_zones.raw[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#NAME}']`</p></li></ul>|
|HTTP server zone [{#NAME}]: Processing|<p>The number of client requests that are currently being processed.</p>|Dependent item|nginx.http.server_zones.processing[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.processing`</p></li></ul>|
|HTTP server zone [{#NAME}]: Requests, rate|<p>The total number of client requests received from clients per second.</p>|Dependent item|nginx.http.server_zones.requests.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.requests`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Responses 1xx, rate|<p>The number of responses with `1xx` status code per second.</p>|Dependent item|nginx.http.server_zones.responses.1xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.1xx`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Responses 2xx, rate|<p>The number of responses with `2xx` status code per second.</p>|Dependent item|nginx.http.server_zones.responses.2xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.2xx`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Responses 3xx, rate|<p>The number of responses with `3xx` status code per second.</p>|Dependent item|nginx.http.server_zones.responses.3xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.3xx`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Responses 4xx, rate|<p>The number of responses with `4xx` status code per second.</p>|Dependent item|nginx.http.server_zones.responses.4xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.4xx`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Responses 5xx, rate|<p>The number of responses with `5xx` status code per second.</p>|Dependent item|nginx.http.server_zones.responses.5xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.5xx`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Responses total, rate|<p>The total number of responses sent to clients per second.</p>|Dependent item|nginx.http.server_zones.responses.total.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.total`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Discarded, rate|<p>The total number of requests completed without sending a response per second.</p>|Dependent item|nginx.http.server_zones.discarded.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.discarded`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Received, rate|<p>The total number of bytes received from clients per second.</p>|Dependent item|nginx.http.server_zones.received.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.received`</p></li><li>Change per second</li></ul>|
|HTTP server zone [{#NAME}]: Sent, rate|<p>The total number of bytes sent to clients per second.</p>|Dependent item|nginx.http.server_zones.sent.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sent`</p></li><li>Change per second</li></ul>|

### LLD rule HTTP location zones discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP location zones discovery||Dependent item|nginx.http.location_zones.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for HTTP location zones discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP location zone [{#NAME}]: Raw data|<p>The raw data of the location zone with the name `{#NAME}`.</p>|Dependent item|nginx.http.location_zones.raw[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#NAME}']`</p></li></ul>|
|HTTP location zone [{#NAME}]: Requests, rate|<p>The total number of client requests received from clients per second.</p>|Dependent item|nginx.http.location_zones.requests.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.requests`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Responses 1xx, rate|<p>The number of responses with `1xx` status code per second.</p>|Dependent item|nginx.http.location_zones.responses.1xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.1xx`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Responses 2xx, rate|<p>The number of responses with `2xx` status code per second.</p>|Dependent item|nginx.http.location_zones.responses.2xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.2xx`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Responses 3xx, rate|<p>The number of responses with `3xx` status code per second.</p>|Dependent item|nginx.http.location_zones.responses.3xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.3xx`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Responses 4xx, rate|<p>The number of responses with `4xx` status code per second.</p>|Dependent item|nginx.http.location_zones.responses.4xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.4xx`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Responses 5xx, rate|<p>The number of responses with `5xx` status code per second.</p>|Dependent item|nginx.http.location_zones.responses.5xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.5xx`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Responses total, rate|<p>The total number of responses sent to clients per second.</p>|Dependent item|nginx.http.location_zones.responses.total.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.total`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Discarded, rate|<p>The total number of requests completed without sending a response per second.</p>|Dependent item|nginx.http.location_zones.discarded.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.discarded`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Received, rate|<p>The total number of bytes received from clients per second.</p>|Dependent item|nginx.http.location_zones.received.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.received`</p></li><li>Change per second</li></ul>|
|HTTP location zone [{#NAME}]: Sent, rate|<p>The total number of bytes sent to clients per second.</p>|Dependent item|nginx.http.location_zones.sent.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sent`</p></li><li>Change per second</li></ul>|

### LLD rule HTTP upstreams discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP upstreams discovery||Dependent item|nginx.http.upstreams.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for HTTP upstreams discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP upstream [{#NAME}]: Raw data|<p>The raw data of the HTTP upstream with the name `{#NAME}`.</p>|Dependent item|nginx.http.upstreams.raw[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#NAME}']`</p></li></ul>|
|HTTP upstream [{#NAME}]: Keepalive|<p>The current number of idle keepalive connections.</p>|Dependent item|nginx.http.upstreams.keepalive[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.keepalive`</p></li></ul>|
|HTTP upstream [{#NAME}]: Zombies|<p>The current number of servers removed from the group but still processing active client requests.</p>|Dependent item|nginx.http.upstreams.zombies[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.zombies`</p></li></ul>|
|HTTP upstream [{#NAME}]: Zone|<p>The name of the shared memory zone that keeps the group's configuration and run-time state.</p>|Dependent item|nginx.http.upstreams.zone[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.zone`</p></li><li><p>Discard unchanged with heartbeat: `3h`</p></li></ul>|

### LLD rule HTTP upstream peers discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP upstream peers discovery||Dependent item|nginx.http.upstream.peers.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for HTTP upstream peers discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Raw data|<p>The raw data of the HTTP upstream with the name `[{#UPSTREAM}]`and peer with the name`[{#PEER}]`.</p>|Dependent item|nginx.http.upstream.peer.raw[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#UPSTREAM}'].peers[?(@.server == '{#PEER}')].first()`</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: State|<p>The current state, which may be one of “up”, “draining”, “down”, “unavail”, “checking”, and “unhealthy”.</p>|Dependent item|nginx.http.upstream.peer.state[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.state`</p></li><li><p>Discard unchanged with heartbeat: `3h`</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Active|<p>The current number of active connections.</p>|Dependent item|nginx.http.upstream.peer.active[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.active`</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Requests, rate|<p>The total number of client requests forwarded to this server per second.</p>|Dependent item|nginx.http.upstream.peer.requests.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.requests`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Responses 1xx, rate|<p>The number of responses with `1xx` status code per second.</p>|Dependent item|nginx.http.upstream.peer.responses.1xx.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.1xx`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Responses 2xx, rate|<p>The number of responses with `2xx` status code per second.</p>|Dependent item|nginx.http.upstream.peer.responses.2xx.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.2xx`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Responses 3xx, rate|<p>The number of responses with `3xx` status code per second.</p>|Dependent item|nginx.http.upstream.peer.responses.3xx.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.3xx`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Responses 4xx, rate|<p>The number of responses with `4xx` status code per second.</p>|Dependent item|nginx.http.upstream.peer.responses.4xx.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.4xx`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Responses 5xx, rate|<p>The number of responses with `5xx` status code per second.</p>|Dependent item|nginx.http.upstream.peer.responses.5xx.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.5xx`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Responses total, rate|<p>The total number of responses obtained from this server.</p>|Dependent item|nginx.http.upstream.peer.responses.total.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.total`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Sent, rate|<p>The total number of bytes sent to this server per second.</p>|Dependent item|nginx.http.upstream.peer.sent.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sent`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Received, rate|<p>The total number of bytes received from this server per second.</p>|Dependent item|nginx.http.upstream.peer.received.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.received`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Fails, rate|<p>The total number of unsuccessful attempts to communicate with the server per second.</p>|Dependent item|nginx.http.upstream.peer.fails.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.fails`</p></li><li>Change per second</li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Unavail|<p>Displays how many times the server has become unavailable for client requests (the state - “unavail”) due to the number of unsuccessful attempts reaching the `max_fails` threshold.</p>|Dependent item|nginx.http.upstream.peer.unavail.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.unavail`</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Header time|<p>The average time to get the response header from the server.</p>|Dependent item|nginx.http.upstream.peer.header_time.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.header_time`</p><p>⛔️Custom on fail: Discard value</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Response time|<p>The average time to get the full response from the server.</p>|Dependent item|nginx.http.upstream.peer.response_time.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.response_time`</p><p>⛔️Custom on fail: Discard value</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Health checks, check|<p>The total number of health check requests made.</p>|Dependent item|nginx.http.upstream.peer.health_checks.checks[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.health_checks.checks`</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Health checks, fails|<p>The number of failed health checks.</p>|Dependent item|nginx.http.upstream.peer.health_checks.fails[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.health_checks.fails`</p></li></ul>|
|HTTP upstream [{#UPSTREAM}] peer [{#PEER}]: Health checks, unhealthy|<p>Displays how many times the server has become `unhealthy` (the state - “unhealthy”.</p>|Dependent item|nginx.http.upstream.peer.health_checks.unhealthy[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.health_checks.unhealthy`</p></li></ul>|

### Trigger prototypes for HTTP upstream peers discovery

|Name|Description|Expression|Severity|Dependencies and additional info|
|----|-----------|----------|--------|--------------------------------|
|NGINX Plus: HTTP upstream server is not in UP or DOWN state.||`find(/NGINX Plus by HTTP/nginx.http.upstream.peer.state[{#UPSTREAM},{#PEER}],,"like","up")=0 and find(/NGINX Plus by HTTP/nginx.http.upstream.peer.state[{#UPSTREAM},{#PEER}],,"like","down")=0`|Warning||
|NGINX Plus: Too many HTTP requests with code 4xx||`sum(/NGINX Plus by HTTP/nginx.http.upstream.peer.responses.4xx.rate[{#UPSTREAM},{#PEER}],5m) > (sum(/NGINX Plus by HTTP/nginx.http.upstream.peer.responses.total.rate[{#UPSTREAM},{#PEER}],5m)*({$NGINX.HTTP.UPSTREAM.4XX.MAX.WARN}/100))`|Warning||
|NGINX Plus: Too many HTTP requests with code 5xx||`sum(/NGINX Plus by HTTP/nginx.http.upstream.peer.responses.5xx.rate[{#UPSTREAM},{#PEER}],5m) > (sum(/NGINX Plus by HTTP/nginx.http.upstream.peer.responses.total.rate[{#UPSTREAM},{#PEER}],5m)*({$NGINX.HTTP.UPSTREAM.5XX.MAX.WARN}/100))`|High||

### LLD rule Stream server zones discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Stream server zones discovery||Dependent item|nginx.stream.server_zones.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for Stream server zones discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Stream server zone [{#NAME}]: Raw data|<p>The raw data of server zone with the name `{#NAME}`, configured in the "stream" directive.</p>|Dependent item|nginx.stream.server_zones.raw[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#NAME}']`</p></li></ul>|
|Stream server zone [{#NAME}]: Processing|<p>The number of client connections that are currently being processed.</p>|Dependent item|nginx.stream.server_zones.processing[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.processing`</p></li></ul>|
|Stream server zone [{#NAME}]: Connections, rate|<p>The total number of connections accepted from clients per second.</p>|Dependent item|nginx.stream.server_zones.connections.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.connections`</p></li><li>Change per second</li></ul>|
|Stream server zone [{#NAME}]: Sessions 2xx, rate|<p>The total number of sessions completed with status code `2xx` per second.</p>|Dependent item|nginx.stream.server_zones.sessions.2xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sessions.2xx`</p></li><li>Change per second</li></ul>|
|Stream server zone [{#NAME}]: Sessions 4xx, rate|<p>The total number of sessions completed with status code `4xx` per second.</p>|Dependent item|nginx.stream.server_zones.sessions.4xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sessions.4xx`</p></li><li>Change per second</li></ul>|
|Stream server zone [{#NAME}]: Sessions 5xx, rate|<p>The total number of sessions completed with status code `5xx` per second.</p>|Dependent item|nginx.stream.server_zones.sessions.5xx.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sessions.5xx`</p></li><li>Change per second</li></ul>|
|Stream server zone [{#NAME}]: Sessions total, rate|<p>The total number of completed client sessions per second.</p>|Dependent item|nginx.stream.server_zones.sessions.total.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sessions.total`</p></li><li>Change per second</li></ul>|
|Stream server zone [{#NAME}]: Discarded, rate|<p>The total number of connections completed without creating a session per second.</p>|Dependent item|nginx.stream.server_zones.discarded.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.discarded`</p></li><li>Change per second</li></ul>|
|Stream server zone [{#NAME}]: Received, rate|<p>The total number of bytes received from clients per second.</p>|Dependent item|nginx.stream.server_zones.received.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.received`</p></li><li>Change per second</li></ul>|
|Stream server zone [{#NAME}]: Sent, rate|<p>The total number of bytes sent to clients per second.</p>|Dependent item|nginx.stream.server_zones.sent.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sent`</p></li><li>Change per second</li></ul>|

### LLD rule Stream upstreams discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Stream upstreams discovery||Dependent item|nginx.stream.upstreams.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for Stream upstreams discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Stream upstream [{#NAME}]: Raw data|<p>The raw data of the upstream with the name `[{#UPSTREAM}]`, configured in the "stream" directive.</p>|Dependent item|nginx.stream.upstreams.raw[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#NAME}']`</p></li></ul>|
|Stream upstream [{#NAME}]: Zombies||Dependent item|nginx.stream.upstreams.zombies[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.zombies`</p></li></ul>|
|Stream upstream [{#NAME}]: Zone||Dependent item|nginx.stream.upstreams.zone[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.zone`</p></li><li><p>Discard unchanged with heartbeat: `3h`</p></li></ul>|

### LLD rule Stream upstream peers discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Stream upstream peers discovery||Dependent item|nginx.stream.upstream.peers.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for Stream upstream peers discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Raw data|<p>The raw data of the upstream with the name `[{#UPSTREAM}]`and peer with the name`[{#PEER}]`, configured in the "stream" directive.</p>|Dependent item|nginx.stream.upstream.peer.raw[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#UPSTREAM}'].peers[?(@.server == '{#PEER}')].first()`</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: State|<p>The current state, which may be one of “up”, “draining”, “down”, “unavail”, “checking”, and “unhealthy”.</p>|Dependent item|nginx.stream.upstream.peer.state[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.state`</p></li><li><p>Discard unchanged with heartbeat: `3h`</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Active|<p>The current number of connections.</p>|Dependent item|nginx.stream.upstream.peer.active[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.active`</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Sent, rate|<p>The total number of bytes sent to this server per second.</p>|Dependent item|nginx.stream.upstream.peer.sent.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.sent`</p></li><li>Change per second</li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Received, rate|<p>The total number of bytes received from this server per second.</p>|Dependent item|nginx.stream.upstream.peer.received.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.received`</p></li><li>Change per second</li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Fails, rate|<p>The total number of unsuccessful attempts to communicate with the server per second.</p>|Dependent item|nginx.stream.upstream.peer.fails.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.fails`</p></li><li>Change per second</li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Unavail|<p>Displays how many times the server has  become unavailable for client requests (the state - “unavail”) due to the number of unsuccessful attempts reaching the `max_fails` threshold.</p>|Dependent item|nginx.stream.upstream.peer.unavail.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.unavail`</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Connections|<p>The total number of client connections forwarded to this server.</p>|Dependent item|nginx.stream.upstream.peer.connections.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.connections`</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Connect time|<p>The average time to connect to the upstream server.</p>|Dependent item|nginx.stream.upstream.peer.connect_time.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.connect_time`</p><p>⛔️Custom on fail: Discard value</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: First byte time|<p>The average time to receive the first byte of data.</p>|Dependent item|nginx.stream.upstream.peer.first_byte_time.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.first_byte_time`</p><p>⛔️Custom on fail: Discard value</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Response time|<p>The average time to receive the last byte of data.</p>|Dependent item|nginx.stream.upstream.peer.response_time.rate[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.response_time`</p><p>⛔️Custom on fail: Discard value</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Health checks, check|<p>The total number of health check requests made.</p>|Dependent item|nginx.stream.upstream.peer.health_checks.checks[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.health_checks.checks`</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Health checks, fails|<p>The number of failed health checks.</p>|Dependent item|nginx.stream.upstream.peer.health_checks.fails[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.health_checks.fails`</p></li></ul>|
|Stream upstream [{#UPSTREAM}] peer [{#PEER}]: Health checks, unhealthy|<p>Displays how many times the server has become `unhealthy` (the state - “unhealthy”).</p>|Dependent item|nginx.stream.upstream.peer.health_checks.unhealthy[{#UPSTREAM},{#PEER}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.health_checks.unhealthy`</p></li></ul>|

### Trigger prototypes for Stream upstream peers discovery

|Name|Description|Expression|Severity|Dependencies and additional info|
|----|-----------|----------|--------|--------------------------------|
|NGINX Plus: Stream upstream server is not in UP or DOWN state.||`find(/NGINX Plus by HTTP/nginx.stream.upstream.peer.state[{#UPSTREAM},{#PEER}],,"like","up")=0 and find(/NGINX Plus by HTTP/nginx.stream.upstream.peer.state[{#UPSTREAM},{#PEER}],,"like","down")=0`|Warning||

### LLD rule Resolvers discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Resolvers discovery||Dependent item|nginx.resolvers.discovery<p>**Preprocessing**</p><ul><li><p>JavaScript: `The text is too long. Please see the template.`</p></li><li><p>Discard unchanged with heartbeat: `30m`</p></li></ul>|

### Item prototypes for Resolvers discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Resolver [{#NAME}]: Raw data|<p>The raw data of the `Resolver` with the name `{#NAME}`.</p>|Dependent item|nginx.resolvers.raw[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$['{#NAME}']`</p></li></ul>|
|Resolver [{#NAME}]: Requests name, rate|<p>The total number of requests to resolve names to addresses per second.</p>|Dependent item|nginx.resolvers.requests.name.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.requests.name`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Requests srv, rate|<p>The total number of requests to resolve SRV records per second.</p>|Dependent item|nginx.resolvers.requests.srv.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.requests.srv`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Requests addr, rate|<p>The total number of requests to resolve addresses to names per second.</p>|Dependent item|nginx.resolvers.requests.addr.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.requests.addr`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses noerror, rate|<p>The total number of successful responses per second.</p>|Dependent item|nginx.resolvers.responses.noerror.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.noerror`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses formerr, rate|<p>The total number of `FORMERR` (format error) responses per second.</p>|Dependent item|nginx.resolvers.responses.formerr.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.formerr`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses servfail, rate|<p>The total number of `SERVFAIL` (server failure) responses per second.</p>|Dependent item|nginx.resolvers.responses.servfail.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.servfail`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses nxdomain, rate|<p>The total number of `NXDOMAIN` (host not found) responses per second.</p>|Dependent item|nginx.resolvers.responses.nxdomain.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.nxdomain`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses notimp, rate|<p>The total number of `NOTIMP` (unimplemented) responses per second.</p>|Dependent item|nginx.resolvers.responses.notimp.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.notimp`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses refused, rate|<p>The total number of `REFUSED` (operation refused) responses per second.</p>|Dependent item|nginx.resolvers.responses.refused.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.refused`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses timedout, rate|<p>The total number of timed out requests per second.</p>|Dependent item|nginx.resolvers.responses.timedout.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.timedout`</p></li><li>Change per second</li></ul>|
|Resolver [{#NAME}]: Responses unknown, rate|<p>The total number of requests completed with an unknown error per second.</p>|Dependent item|nginx.resolvers.responses.unknown.rate[{#NAME}]<p>**Preprocessing**</p><ul><li><p>JSON Path: `$.responses.unknown`</p></li><li>Change per second</li></ul>|

## Feedback

Please report any issues with the template at [`https://support.zabbix.com`](https://support.zabbix.com)

You can also provide feedback, discuss the template, or ask for help at [`ZABBIX forums`](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback)

