
# Apache by Zabbix agent

## Overview

This template is designed for the effortless deployment of Apache monitoring by Zabbix via Zabbix agent and doesn't require any external scripts.
The template `Apache by Zabbix agent` - collects metrics by polling [mod_status](https://httpd.apache.org/docs/current/mod/mod_status.html) locally with Zabbix agent:
  
```text
127.0.0.1
ServerVersion: Apache/2.4.41 (Unix)
ServerMPM: event
Server Built: Aug 14 2019 00:35:10
CurrentTime: Friday, 16-Aug-2019 12:38:40 UTC
RestartTime: Wednesday, 14-Aug-2019 07:58:26 UTC
ParentServerConfigGeneration: 1
ParentServerMPMGeneration: 0
ServerUptimeSeconds: 189613
ServerUptime: 2 days 4 hours 40 minutes 13 seconds
Load1: 4.60
Load5: 1.20
Load15: 0.47
Total Accesses: 27860
Total kBytes: 33011
Total Duration: 54118
CPUUser: 18.02
CPUSystem: 31.76
CPUChildrenUser: 0
CPUChildrenSystem: 0
CPULoad: .0262535
Uptime: 189613
ReqPerSec: .146931
BytesPerSec: 178.275
BytesPerReq: 1213.33
DurationPerReq: 1.9425
BusyWorkers: 7
IdleWorkers: 93
Processes: 4
Stopping: 0
BusyWorkers: 7
IdleWorkers: 93
ConnsTotal: 13
ConnsAsyncWriting: 0
ConnsAsyncKeepAlive: 5
ConnsAsyncClosing: 0
Scoreboard: ...

```
  
It also uses Zabbix agent to collect `Apache` Linux process statistics such as CPU usage, memory usage, and whether the process is running or not.

## Requirements

Zabbix version: 7.0 and higher.

## Tested versions

This template has been tested on:
- Apache 2.4.41

## Configuration

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

## Setup

See the setup instructions for [mod_status](https://httpd.apache.org/docs/current/mod/mod_status.html).

Check the availability of the module with this command line: `httpd -M 2>/dev/null | grep status_module`

This is an example configuration of the Apache web server:

```text
<Location "/server-status">
  SetHandler server-status
  Require host example.com
</Location>
```

If you use another path, then do not forget to change the `{$APACHE.STATUS.PATH}` macro.
Install and setup [Zabbix agent](https://www.zabbix.com/documentation/7.0/manual/installation/install_from_packages).

### Macros used

|Name|Description|Default|
|----|-----------|-------|
|{$APACHE.STATUS.HOST}|
The hostname or IP address of the Apache status page.
|`127.0.0.1`|
|{$APACHE.STATUS.PORT}|
The port of the Apache status page.
|`80`|
|{$APACHE.STATUS.PATH}|
The URL path.
|`server-status?auto`|
|{$APACHE.STATUS.SCHEME}|
The request scheme, which may be either HTTP or HTTPS.
|`http`|
|{$APACHE.RESPONSE_TIME.MAX.WARN}|
The maximum Apache response time expressed in seconds for a trigger expression.
|`10`|
|{$APACHE.PROCESS_NAME}|
The process name filter for the Apache process discovery.
|`(httpd\|apache2)`|
|{$APACHE.PROCESS.NAME.PARAMETER}|
The process name of the Apache web server used in the item key `proc.get`. It could be specified if the correct process name is known.
||

### Items

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Get status|
Getting data from a machine-readable version of the Apache status page.

For more information see Apache Module [mod_status](https://httpd.apache.org/docs/current/mod/mod_status.html).
|Zabbix agent|web.page.get["{$APACHE.STATUS.SCHEME}://{$APACHE.STATUS.HOST}:{$APACHE.STATUS.PORT}/{$APACHE.STATUS.PATH}"]
**Preprocessing**

- 
JavaScript: `The text is too long. Please see the template.`

|
|Service ping||Zabbix agent|net.tcp.service[http,"{$APACHE.STATUS.HOST}","{$APACHE.STATUS.PORT}"]
**Preprocessing**

- 
Discard unchanged with heartbeat: `10m`

|
|Service response time||Zabbix agent|net.tcp.service.perf[http,"{$APACHE.STATUS.HOST}","{$APACHE.STATUS.PORT}"]|
|Total bytes|
The total bytes served.
|Dependent item|apache.bytes
**Preprocessing**

- 
JSON Path: `$["Total kBytes"]`

- 
Custom multiplier: `1024`

|
|Bytes per second|
It is calculated as a rate of change for total bytes statistics.

`BytesPerSec` is not used, as it counts the average since the last Apache server start.
|Dependent item|apache.bytes.rate
**Preprocessing**

- 
JSON Path: `$["Total kBytes"]`

- 
Custom multiplier: `1024`

- Change per second
|
|Requests per second|
It is calculated as a rate of change for the "Total requests" statistics.

`ReqPerSec` is not used, as it counts the average since the last Apache server start.
|Dependent item|apache.requests.rate
**Preprocessing**

- 
JSON Path: `$["Total Accesses"]`

- Change per second
|
|Total requests|
The total number of the Apache server accesses.
|Dependent item|apache.requests
**Preprocessing**

- 
JSON Path: `$["Total Accesses"]`

|
|Uptime|
The service uptime expressed in seconds.
|Dependent item|apache.uptime
**Preprocessing**

- 
JSON Path: `$.ServerUptimeSeconds`

|
|Version|
The Apache service version.
|Dependent item|apache.version
**Preprocessing**

- 
JSON Path: `$.ServerVersion`

- 
Discard unchanged with heartbeat: `1d`

|
|Total workers busy|
The total number of busy worker threads/processes.
|Dependent item|apache.workers_total.busy
**Preprocessing**

- 
JSON Path: `$.BusyWorkers`

|
|Total workers idle|
The total number of idle worker threads/processes.
|Dependent item|apache.workers_total.idle
**Preprocessing**

- 
JSON Path: `$.IdleWorkers`

|
|Workers closing connection|
The number of workers in closing state.
|Dependent item|apache.workers.closing
**Preprocessing**

- 
JSON Path: `$.Workers.closing`

|
|Workers DNS lookup|
The number of workers in `dnslookup` state.
|Dependent item|apache.workers.dnslookup
**Preprocessing**

- 
JSON Path: `$.Workers.dnslookup`

|
|Workers finishing|
The number of workers in finishing state.
|Dependent item|apache.workers.finishing
**Preprocessing**

- 
JSON Path: `$.Workers.finishing`

|
|Workers idle cleanup|
The number of workers in cleanup state.
|Dependent item|apache.workers.cleanup
**Preprocessing**

- 
JSON Path: `$.Workers.cleanup`

|
|Workers keepalive (read)|
The number of workers in `keepalive` state.
|Dependent item|apache.workers.keepalive
**Preprocessing**

- 
JSON Path: `$.Workers.keepalive`

|
|Workers logging|
The number of workers in logging state.
|Dependent item|apache.workers.logging
**Preprocessing**

- 
JSON Path: `$.Workers.logging`

|
|Workers reading request|
The number of workers in reading state.
|Dependent item|apache.workers.reading
**Preprocessing**

- 
JSON Path: `$.Workers.reading`

|
|Workers sending reply|
The number of workers in sending state.
|Dependent item|apache.workers.sending
**Preprocessing**

- 
JSON Path: `$.Workers.sending`

|
|Workers slot with no current process|
The number of slots with no current process.
|Dependent item|apache.workers.slot
**Preprocessing**

- 
JSON Path: `$.Workers.slot`

|
|Workers starting up|
The number of workers in starting state.
|Dependent item|apache.workers.starting
**Preprocessing**

- 
JSON Path: `$.Workers.starting`

|
|Workers waiting for connection|
The number of workers in waiting state.
|Dependent item|apache.workers.waiting
**Preprocessing**

- 
JSON Path: `$.Workers.waiting`

|
|Get processes summary|
The aggregated data of summary metrics for all processes.
|Zabbix agent|proc.get[{$APACHE.PROCESS.NAME.PARAMETER},,,summary]|

### Triggers

|Name|Description|Expression|Severity|Dependencies and additional info|
|----|-----------|----------|--------|--------------------------------|
|Apache: Service has been restarted|
Uptime is less than 10 minutes.
|`last(/Apache by Zabbix agent/apache.uptime)<10m`|Info|**Manual close**: Yes|
|Apache: Version has changed|
Apache version has changed. Acknowledge to close the problem manually.
|`last(/Apache by Zabbix agent/apache.version,#1)<>last(/Apache by Zabbix agent/apache.version,#2) and length(last(/Apache by Zabbix agent/apache.version))>0`|Info|**Manual close**: Yes|

### LLD rule Event MPM discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Event MPM discovery|
The discovery of additional metrics if the event Multi-Processing Module (MPM) is used.

For more details see [Apache MPM event](https://httpd.apache.org/docs/current/mod/event.html).
|Dependent item|apache.mpm.event.discovery
**Preprocessing**

- 
JavaScript: `The text is too long. Please see the template.`

- 
Discard unchanged with heartbeat: `3h`

|

### Item prototypes for Event MPM discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Connections async closing|
The number of asynchronous connections in closing state (applicable only to the event MPM).
|Dependent item|apache.connections[async_closing{#SINGLETON}]
**Preprocessing**

- 
JSON Path: `$.ConnsAsyncClosing`

|
|Connections async keepalive|
The number of asynchronous connections in keepalive state (applicable only to the event MPM).
|Dependent item|apache.connections[async_keep_alive{#SINGLETON}]
**Preprocessing**

- 
JSON Path: `$.ConnsAsyncKeepAlive`

|
|Connections async writing|
The number of asynchronous connections in writing state (applicable only to the event MPM).
|Dependent item|apache.connections[async_writing{#SINGLETON}]
**Preprocessing**

- 
JSON Path: `$.ConnsAsyncWriting`

|
|Connections total|
The number of total connections.
|Dependent item|apache.connections[total{#SINGLETON}]
**Preprocessing**

- 
JSON Path: `$.ConnsTotal`

|
|Bytes per request|
The average number of client requests per second.
|Dependent item|apache.bytes[per_request{#SINGLETON}]
**Preprocessing**

- 
JSON Path: `$.BytesPerReq`

|
|Number of async processes|
The number of asynchronous processes.
|Dependent item|apache.process[num{#SINGLETON}]
**Preprocessing**

- 
JSON Path: `$.Processes`

|

### LLD rule Apache process discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|Apache process discovery|
The discovery of the Apache process summary.
|Dependent item|apache.proc.discovery|

### Item prototypes for Apache process discovery

|Name|Description|Type|Key and additional info|
|----|-----------|----|-----------------------|
|CPU utilization|
The percentage of the CPU utilization by a process {#APACHE.NAME}.
|Zabbix agent|proc.cpu.util[{#APACHE.NAME}]|
|Get process data|
The summary metrics aggregated by a process {#APACHE.NAME}.
|Dependent item|apache.proc.get[{#APACHE.NAME}]
**Preprocessing**

- 
JSON Path: `$.[?(@["name"]=="{#APACHE.NAME}")].first()`

⛔️Custom on fail: Set value to: `Failed to retrieve process {#APACHE.NAME} data`

|
|Memory usage (rss)|
The summary of resident set size memory used by a process {#APACHE.NAME} expressed in bytes.
|Dependent item|apache.proc.rss[{#APACHE.NAME}]
**Preprocessing**

- 
JSON Path: `$.rss`

⛔️Custom on fail: Discard value

|
|Memory usage (vsize)|
The summary of virtual memory used by a process {#APACHE.NAME} expressed in bytes.
|Dependent item|apache.proc.vmem[{#APACHE.NAME}]
**Preprocessing**

- 
JSON Path: `$.vsize`

⛔️Custom on fail: Discard value

|
|Memory usage, %|
The percentage of real memory used by a process {#APACHE.NAME}.
|Dependent item|apache.proc.pmem[{#APACHE.NAME}]
**Preprocessing**

- 
JSON Path: `$.pmem`

⛔️Custom on fail: Discard value

|
|Number of running processes|
The number of running processes {#APACHE.NAME}.
|Dependent item|apache.proc.num[{#APACHE.NAME}]
**Preprocessing**

- 
JSON Path: `$.processes`

⛔️Custom on fail: Set value to: `0`

- 
Discard unchanged with heartbeat: `1h`

|

### Trigger prototypes for Apache process discovery

|Name|Description|Expression|Severity|Dependencies and additional info|
|----|-----------|----------|--------|--------------------------------|
|Apache: Process is not running||`last(/Apache by Zabbix agent/apache.proc.num[{#APACHE.NAME}])=0`|High||
|Apache: Service is down||`last(/Apache by Zabbix agent/net.tcp.service[http,"{$APACHE.STATUS.HOST}","{$APACHE.STATUS.PORT}"])=0 and last(/Apache by Zabbix agent/apache.proc.num[{#APACHE.NAME}])>0`|Average|**Manual close**: Yes|
|Apache: Failed to fetch status page|
Zabbix has not received any data for items for the last 30 minutes.
|`nodata(/Apache by Zabbix agent/web.page.get["{$APACHE.STATUS.SCHEME}://{$APACHE.STATUS.HOST}:{$APACHE.STATUS.PORT}/{$APACHE.STATUS.PATH}"],30m)=1 and last(/Apache by Zabbix agent/apache.proc.num[{#APACHE.NAME}])>0`|Warning|**Manual close**: Yes
**Depends on**:

- Apache: Service is down
|
|Apache: Service response time is too high||`min(/Apache by Zabbix agent/net.tcp.service.perf[http,"{$APACHE.STATUS.HOST}","{$APACHE.STATUS.PORT}"],5m)>{$APACHE.RESPONSE_TIME.MAX.WARN} and last(/Apache by Zabbix agent/apache.proc.num[{#APACHE.NAME}])>0`|Warning|**Manual close**: Yes
**Depends on**:

- Apache: Service is down
|

## 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)

