Apache Plugin

Monitor Apache HTTP Server performance with real-time metrics covering requests, workers, traffic, and server load.

Overview

The Apache plugin collects performance metrics from Apache's mod_status module including:

  • Request Statistics - Total requests, requests per second, total traffic, processing time
  • Worker Status - Busy workers, idle workers
  • Traffic Metrics - Bytes served, bytes per second, bytes per request
  • CPU Usage - User time, system time, child process times
  • System Load - 1/5/15-minute load averages
  • Server Info - Uptime, Apache version, MPM module

Requirements

Apache Version

  • Minimum: Apache 2.4
  • Recommended: Apache 2.4.41 or later
  • Tested with: Apache 2.4.41, 2.4.52, 2.4.54, 2.4.57

Apache Modules

Required:

  • mod_status - Server status module

Check if enabled:

# Ubuntu/Debian
apache2ctl -M | grep status

# CentOS/RHEL
httpctl -M | grep status

Enable if missing:

# Ubuntu/Debian
sudo a2enmod status
sudo systemctl restart apache2

# CentOS/RHEL
# mod_status is usually enabled by default

Python Dependencies

No additional Python packages required - uses standard library urllib.

Configuration

Basic Configuration

plugins:
  apache:
    enabled: true
    status_url: http://127.0.0.1/server-status?auto

With Custom Port

plugins:
  apache:
    enabled: true
    status_url: http://127.0.0.1:8080/server-status?auto

With Authentication

plugins:
  apache:
    enabled: true
    status_url: http://127.0.0.1/server-status?auto
    username: monitor
    password: your-password

All Configuration Options

plugins:
  apache:
    enabled: true                                      # Enable/disable plugin
    status_url: http://127.0.0.1/server-status?auto    # Status URL
    username: monitor                                  # HTTP auth username (optional)
    password: password                                 # HTTP auth password (optional)
    timeout: 10                                        # Request timeout (seconds)
    verify_ssl: true                                   # Verify SSL certificates

Environment Variables

Configuration can be overridden with environment variables:

export APACHE_STATUS_URL="http://127.0.0.1/server-status?auto"
export APACHE_USERNAME="monitor"
export APACHE_PASSWORD="password"

Apache Setup

Configure mod_status

For Apache 2.4:

Create configuration file:

sudo nano /etc/apache2/conf-available/status.conf

Add configuration:

<IfModule mod_status.c>
    <Location /server-status>
        SetHandler server-status
        Require local
        # Or allow specific IP
        # Require ip 127.0.0.1 ::1
    </Location>

    # Extended status provides detailed metrics
    ExtendedStatus On
</IfModule>

Enable configuration:

# Ubuntu/Debian
sudo a2enconf status
sudo systemctl reload apache2

# CentOS/RHEL
# Include in /etc/httpd/conf.d/status.conf
sudo systemctl reload httpd

Alternative: Add to VirtualHost

<VirtualHost *:80>
    ServerName example.com

    <Location /server-status>
        SetHandler server-status
        Require local
    </Location>
</VirtualHost>

ExtendedStatus Configuration

Enable ExtendedStatus for detailed metrics:

# In apache2.conf or httpd.conf
ExtendedStatus On

Restart Apache:

sudo systemctl restart apache2  # Ubuntu/Debian
sudo systemctl restart httpd    # CentOS/RHEL

Security Configuration

Restrict access to localhost only:

<Location /server-status>
    SetHandler server-status
    Require local
</Location>

Allow specific IP address:

<Location /server-status>
    SetHandler server-status
    Require ip 127.0.0.1 10.0.0.5
</Location>

With HTTP Basic Authentication:

<Location /server-status>
    SetHandler server-status
    AuthType Basic
    AuthName "Server Status"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Location>

Create password file:

sudo htpasswd -c /etc/apache2/.htpasswd monitor

Disable Logging for Status Endpoint

To reduce log noise:

<Location /server-status>
    SetHandler server-status
    SetEnv dont-log 1
    Require local
</Location>

Or use CustomLog directive:

CustomLog logs/access_log combined env=!dont-log

Collected Metrics

Request Metrics

Metric Description Unit Type
total_accesses Total requests since startup Count Counter
total_kbytes Total traffic served KB Counter
total_duration Total request processing time Microseconds Counter
req_per_sec Requests per second req/s Gauge
bytes_per_sec Bytes per second B/s Gauge
bytes_per_req Average bytes per request Bytes Gauge

Worker Metrics

Metric Description Unit Type
busy_workers Busy worker threads/processes Count Gauge
idle_workers Idle worker threads/processes Count Gauge

CPU Metrics

Metric Description Unit Type
cpu_user CPU user time Seconds Gauge
cpu_system CPU system time Seconds Gauge
cpu_children_user CPU user time (child processes) Seconds Gauge
cpu_children_system CPU system time (child processes) Seconds Gauge

Server Metrics

Metric Description Unit Type
uptime_seconds Server uptime Seconds Gauge
load1 1-minute load average Load Gauge
load5 5-minute load average Load Gauge
load15 15-minute load average Load Gauge
server_version Apache server version String Info
server_mpm Apache MPM module name String Info

Note: The plugin collects numeric metrics only. Scoreboard parsing (worker state breakdown) is not currently implemented.

Dashboard Metrics

The StatusRadar dashboard displays:

Overview Card

  • Requests/sec - Current request rate
  • Busy Workers - Active worker count
  • System Load - Server load averages
  • Traffic - Bytes per second

Request Rate Chart

  • Requests per second over time
  • Traffic (bytes/sec) over time
  • Average request size

Worker Status Chart

  • Busy vs idle workers
  • Worker pool utilization
  • Worker saturation alerts

CPU Usage Chart

  • CPU user vs system time
  • Child process CPU time
  • Total CPU consumption

System Load Chart

  • 1-minute, 5-minute, 15-minute load averages
  • Load trends over time

Installation

Quick Install

PLUGINS='apache' \
TOKEN='your-agent-token' \
APACHE_STATUS_URL='http://127.0.0.1/server-status?auto' \
bash -c "$(curl -sL https://statusradar.dev/install-agent.sh)"

Install on Existing Agent

  1. Enable mod_status (see Apache Setup above)

  2. Configure agent:

    sudo nano /opt/statusradar/config/agent.yaml

    Add:

    plugins:
      apache:
        enabled: true
        status_url: http://127.0.0.1/server-status?auto
  3. Restart agent:

    sudo systemctl restart statusradar-agent
  4. Verify:

    sudo journalctl -u statusradar-agent -n 50 --no-pager | grep apache

    Expected:

    INFO: Plugin apache: Metrics collected successfully
    INFO: Plugin apache: Uptime 86400s, 1234.5 req/sec

Testing

Manual Plugin Test

cd /opt/statusradar
python3 plugins/apache_plugin.py

Expected Output:

Plugin: apache
Enabled: True
Available: True

Collecting metrics...
{
  "total_accesses": 1234567,
  "total_kbytes": 5678912,
  "total_duration": 987654321,
  "uptime_seconds": 86400,
  "cpu_user": 1234.56,
  "cpu_system": 567.89,
  "cpu_children_user": 12.34,
  "cpu_children_system": 5.67,
  "busy_workers": 8,
  "idle_workers": 142,
  "load1": 0.52,
  "load5": 0.48,
  "load15": 0.45,
  "req_per_sec": 45.2,
  "bytes_per_sec": 123456,
  "bytes_per_req": 2731,
  "server_version": "Apache/2.4.52 (Ubuntu)",
  "server_mpm": "event"
}

Test Status Endpoint

# Check status endpoint is accessible
curl http://127.0.0.1/server-status?auto

# Expected output (partial):
# Total Accesses: 1234
# Total kBytes: 5678
# CPULoad: .123
# Uptime: 86400
# ReqPerSec: 45.2
# BytesPerSec: 123456
# BytesPerReq: 2731
# BusyWorkers: 8
# IdleWorkers: 142

Verify ExtendedStatus

curl http://127.0.0.1/server-status

# Should show detailed scoreboard
# If you only see basic stats, ExtendedStatus is not enabled

Troubleshooting

Plugin Not Collecting Metrics

Check 1: Is Apache running?

sudo systemctl status apache2  # Ubuntu/Debian
sudo systemctl status httpd    # CentOS/RHEL

Check 2: Is mod_status enabled?

apache2ctl -M | grep status
# Should show: status_module (shared)

Check 3: Is status endpoint accessible?

curl http://127.0.0.1/server-status?auto

# If 404, mod_status is not configured
# If 403, IP restrictions are blocking access

Check 4: Check agent logs

sudo journalctl -u statusradar-agent -n 100 --no-pager | grep apache

Common Errors

"404 Not Found"

Error:

ERROR: Plugin apache: HTTP 404 - /server-status not found

Causes:

  1. mod_status not enabled
  2. Status location not configured

Solution:

# Enable mod_status
sudo a2enmod status

# Create status configuration
sudo nano /etc/apache2/conf-available/status.conf

# Add:
<IfModule mod_status.c>
    <Location /server-status>
        SetHandler server-status
        Require local
    </Location>
    ExtendedStatus On
</IfModule>

# Enable and reload
sudo a2enconf status
sudo systemctl reload apache2

"403 Forbidden"

Error:

ERROR: Plugin apache: HTTP 403 - Access forbidden

Cause: IP restrictions blocking access

Solution:

<Location /server-status>
    SetHandler server-status
    Require local  # Allows 127.0.0.1 and ::1
    # Or explicitly allow agent IP:
    # Require ip 127.0.0.1 10.0.0.5
</Location>

"ExtendedStatus is disabled"

Warning:

WARNING: Plugin apache: Limited metrics - ExtendedStatus is disabled

Cause: ExtendedStatus directive not set

Solution:

# In apache2.conf or httpd.conf
ExtendedStatus On

Restart Apache:

sudo systemctl restart apache2

"Connection refused"

Error:

ERROR: Plugin apache: Connection refused

Causes:

  1. Wrong status_url
  2. Apache not running
  3. Firewall blocking localhost connections

Solution:

# Check Apache is running
sudo systemctl status apache2

# Check port
sudo netstat -tlnp | grep apache2

# Test connection
curl -v http://127.0.0.1/server-status?auto

Performance Impact

On Apache

Minimal impact:

  • mod_status serves pre-calculated statistics
  • No additional logging or processing
  • Response time: < 1ms

Benchmark:

  • Apache overhead: < 0.01% CPU
  • No measurable performance degradation
  • Safe for high-traffic production servers

On Agent

Resource usage:

  • Memory: +5 MB
  • CPU: +1% during collection
  • Network: +0.5 KB per collection

Collection time: < 0.1 seconds

Use Cases

1. Worker Saturation Monitoring

Monitor:

  • Busy workers vs total workers
  • Worker pool utilization percentage
  • Idle worker availability

Alert on:

  • Busy workers > 90% of total
  • No idle workers available
  • Idle workers < 5

2. Request Rate Analysis

Monitor:

  • Requests per second
  • Request rate trends
  • Traffic patterns

Alert on:

  • Request rate spike > 3× baseline
  • Sudden drop in requests (outage)

3. CPU Usage Monitoring

Monitor:

  • Apache CPU usage (user + system)
  • Child process CPU time
  • CPU time correlation with requests

Alert on:

  • CPU time growing faster than requests
  • High system time (I/O bottleneck)

4. Traffic Analysis

Monitor:

  • Bytes per second
  • Bytes per request
  • Total traffic served

Alert on:

  • Bandwidth saturation
  • Unusually large requests
  • Traffic spike

5. System Load Monitoring

Monitor:

  • System load averages (1/5/15 min)
  • Load trend analysis
  • Load correlation with request rate

Alert on:

  • Load1 > number of CPU cores
  • Load trend increasing rapidly

Best Practices

1. Tune Worker Settings

For prefork MPM:

<IfModule mpm_prefork_module>
    StartServers             5
    MinSpareServers          5
    MaxSpareServers         10
    MaxRequestWorkers      150
    MaxConnectionsPerChild   0
</IfModule>

For worker/event MPM:

<IfModule mpm_worker_module>
    StartServers             2
    MinSpareThreads         25
    MaxSpareThreads         75
    ThreadLimit             64
    ThreadsPerChild         25
    MaxRequestWorkers      150
    MaxConnectionsPerChild   0
</IfModule>

Monitor and adjust based on busy/idle worker ratios.

2. Enable ExtendedStatus

Always enable for detailed monitoring:

ExtendedStatus On

Overhead is negligible.

3. Monitor MPM Choice

Prefork: One process per connection

  • Good for: Non-thread-safe modules (mod_php)
  • Memory: Higher (each process loads modules)
  • Scalability: Lower

Worker/Event: Threads + processes

  • Good for: Modern deployments
  • Memory: Lower (shared modules)
  • Scalability: Higher

Event MPM (recommended):

  • Best performance
  • Async keep-alive handling
  • Lowest memory footprint

4. Set Appropriate Limits

MaxRequestWorkers calculation:

MaxRequestWorkers = (Total RAM - OS - Other) / (Apache process size)

Example:
Total RAM: 4GB
Reserved: 1GB (OS + other services)
Apache process: 25MB
MaxRequestWorkers = 3072MB / 25MB ≈ 120

5. Disable Status Logging

Prevent log noise:

<Location /server-status>
    SetHandler server-status
    SetEnv dont-log 1
    Require local
</Location>

Apache MPM Guide

Check Current MPM

# Ubuntu/Debian
apache2ctl -V | grep MPM

# CentOS/RHEL
httpd -V | grep MPM

Switch MPM (Ubuntu/Debian)

# Disable current MPM
sudo a2dismod mpm_prefork

# Enable new MPM
sudo a2enmod mpm_event

# Restart Apache
sudo systemctl restart apache2

MPM Performance Comparison

MPM Memory Concurrency Thread-Safe Best For
Prefork High Low No mod_php, legacy apps
Worker Medium Medium Yes General purpose
Event Low High Yes Modern sites, high traffic

Recommendation: Use Event MPM for best performance unless you need non-thread-safe modules.

Monitoring Dashboard Setup

Key Metrics to Display

Primary:

  1. Requests per second
  2. Busy workers / Total workers
  3. System load (load1, load5, load15)

Secondary: 4. Bytes per second 5. CPU usage (user + system) 6. Uptime

Alert Configuration

Recommended thresholds:

# High worker utilization
busy_workers / (busy_workers + idle_workers) > 0.9

# System overload
load1 > cpu_cores

# Request spike
req_per_sec > baseline × 3

# No idle workers
idle_workers < 5

# High CPU time
cpu_user + cpu_system > baseline × 2

Advanced Configuration

Multiple Apache Instances

Monitor multiple Apache instances:

plugins:
  apache_main:
    enabled: true
    status_url: http://127.0.0.1:80/server-status?auto

  apache_ssl:
    enabled: true
    status_url: https://127.0.0.1:443/server-status?auto
    verify_ssl: false  # If using self-signed cert

Reverse Proxy Behind Nginx

If Apache is behind Nginx proxy:

<Location /server-status>
    SetHandler server-status
    Require ip 127.0.0.1 10.0.0.5  # Allow nginx backend IP
</Location>

Docker Container

Monitor Apache in Docker:

plugins:
  apache:
    enabled: true
    status_url: http://apache-container:80/server-status?auto

Or expose status on different port:

Listen 8080
<VirtualHost *:8080>
    <Location /server-status>
        SetHandler server-status
        Require all granted
    </Location>
</VirtualHost>

Example Configurations

Basic Production

plugins:
  apache:
    enabled: true
    status_url: http://127.0.0.1/server-status?auto

With SSL and Authentication

plugins:
  apache:
    enabled: true
    status_url: https://127.0.0.1/server-status?auto
    username: monitor
    password: ${APACHE_PASSWORD}
    verify_ssl: true

Custom Port

plugins:
  apache:
    enabled: true
    status_url: http://127.0.0.1:8080/server-status?auto

Limitations

Current Limitations

  1. No per-vhost metrics - Server-wide statistics only
  2. No scoreboard parsing - Worker state breakdown not collected
  3. No request duration metrics - Use access logs for slow requests
  4. No error rate metrics - Monitor error logs separately

Scalability

Tested with:

  • Apache serving 10,000+ req/sec
  • 500+ worker processes
  • Multi-GB/sec traffic

Performance:

  • Status endpoint response time constant regardless of load
  • No impact on Apache performance

Next Steps