Nginx Plugin
Monitor Nginx web server with real-time connection statistics, request rates, and worker status.
Overview
The Nginx plugin collects metrics from Nginx's stub_status module including:
- Connection Statistics - Active connections, accepts, handled connections
- Request Metrics - Total requests, requests per second
- Worker States - Reading, writing, waiting connections
- Connection Rate - Connection accept/drop rate
Requirements
Nginx Version
- Any version with stub_status module compiled
- Most common: Nginx 1.14+, 1.18+, 1.20+, 1.22+, 1.24+
- Tested with: Nginx 1.18, 1.20, 1.22, 1.24, 1.25
Python Dependencies
pip install requests>=2.28.0
Auto-installed when using PLUGINS=nginx
during agent installation.
Nginx Module
Nginx must be compiled with http_stub_status_module
:
# Check if module is available
nginx -V 2>&1 | grep -o with-http_stub_status_module
Expected output: with-http_stub_status_module
Note: Most pre-built Nginx packages include this module by default.
Configuration
Basic Configuration
plugins:
nginx:
enabled: true
status_url: http://127.0.0.1/nginx_status
Custom Status URL
plugins:
nginx:
enabled: true
status_url: http://127.0.0.1:8080/status
Remote Nginx Server
plugins:
nginx:
enabled: true
status_url: http://nginx-server.example.com/nginx_status
All Configuration Options
plugins:
nginx:
enabled: true # Enable/disable plugin
status_url: http://127.0.0.1/nginx_status # Nginx stub_status URL
timeout: 5 # Request timeout in seconds
Environment Variables
Configuration can be overridden with environment variables:
export NGINX_STATUS_URL="http://127.0.0.1/nginx_status"
Nginx Setup
Enable stub_status Module
Edit your Nginx configuration file (e.g., /etc/nginx/sites-available/default
or /etc/nginx/nginx.conf
):
Option 1: Dedicated Server Block (Recommended)
server {
listen 127.0.0.1:80;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Option 2: Add to Existing Server Block
server {
listen 80;
server_name example.com;
# Your existing configuration...
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Option 3: Custom Port
server {
listen 127.0.0.1:8080;
server_name localhost;
location /status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Security Considerations
Important: Always restrict access to stub_status:
location /nginx_status {
stub_status on;
access_log off;
# Only allow localhost
allow 127.0.0.1;
allow ::1;
deny all;
}
For remote monitoring:
location /nginx_status {
stub_status on;
access_log off;
# Allow specific monitoring server IP
allow 10.0.0.100; # Agent server IP
deny all;
}
Test Configuration
# Check Nginx configuration syntax
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
# Test stub_status endpoint
curl http://127.0.0.1/nginx_status
Expected output:
Active connections: 5
server accepts handled requests
1234 1234 5678
Reading: 0 Writing: 1 Waiting: 4
Collected Metrics
Connection Metrics
Metric | Description | Unit | Type |
---|---|---|---|
active_connections |
Currently active client connections | Count | Gauge |
accepts_total |
Total accepted client connections | Count | Counter |
handled_total |
Total handled connections | Count | Counter |
requests_total |
Total client requests | Count | Counter |
dropped_connections |
Dropped connections (accepts - handled) | Count | Counter |
accepts_per_sec |
Connection accept rate | Connections/sec | Gauge |
requests_per_sec |
Request rate | Requests/sec | Gauge |
Connection drop rate:
drop_rate = dropped_connections / accepts_total
Healthy: drop_rate = 0 (no dropped connections)
Worker State Metrics
Metric | Description | Unit | Type |
---|---|---|---|
reading |
Connections reading request headers | Count | Gauge |
writing |
Connections writing responses to clients | Count | Gauge |
waiting |
Idle keep-alive connections | Count | Gauge |
Connection states explained:
- Reading: Nginx is reading the request header from the client
- Writing: Nginx is writing the response back to the client
- Waiting: Keep-alive connections waiting for new requests
Monitoring:
- High
reading
count = slow clients or large request headers - High
writing
count = slow clients or large responses - High
waiting
count = many keep-alive connections (normal)
Dashboard Metrics
The StatusRadar dashboard displays:
Overview Card
- Status - Nginx server up/down
- Active Connections - Current connections
- Requests/sec - Request rate
Connection Chart
- Active connections over time
- Accepts vs handled connections
- Connection drop rate
Worker States Chart
- Reading connections
- Writing connections
- Waiting connections
Request Rate Chart
- Requests per second
- Total requests (cumulative)
Installation
Quick Install
PLUGINS='nginx' \
NGINX_STATUS_URL='http://127.0.0.1/nginx_status' \
TOKEN='your-agent-token' \
bash -c "$(curl -sL https://statusradar.dev/install-agent.sh)"
Install on Existing Agent
-
Configure Nginx stub_status:
sudo nano /etc/nginx/sites-available/default
Add:
location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }
-
Reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
-
Test endpoint:
curl http://127.0.0.1/nginx_status
-
Enable plugin in agent config:
sudo nano /opt/statusradar/config/agent.yaml
Add:
plugins: nginx: enabled: true status_url: http://127.0.0.1/nginx_status
-
Restart agent:
sudo systemctl restart statusradar-agent
-
Verify:
sudo journalctl -u statusradar-agent -n 50 --no-pager | grep nginx
Expected:
INFO: Plugin nginx: Metrics collected successfully
Testing
Manual Plugin Test
cd /opt/statusradar
python3 plugins/nginx_plugin.py
Expected Output:
Plugin: nginx
Enabled: True
Available: True
Collecting metrics...
{
"active_connections": 5,
"accepts_total": 12345,
"handled_total": 12345,
"requests_total": 67890,
"dropped_connections": 0,
"reading": 0,
"writing": 1,
"waiting": 4,
"requests_per_sec": 12.5,
"accepts_per_sec": 2.1
}
Test stub_status Endpoint
# Local test
curl http://127.0.0.1/nginx_status
# With specific port
curl http://127.0.0.1:8080/status
# Remote server
curl http://nginx-server.example.com/nginx_status
# Verbose output
curl -v http://127.0.0.1/nginx_status
Expected output format:
Active connections: 5
server accepts handled requests
12345 12345 67890
Reading: 0 Writing: 1 Waiting: 4
Troubleshooting
Plugin Not Collecting Metrics
Check 1: Is Nginx running?
sudo systemctl status nginx
Check 2: Is stub_status configured?
curl http://127.0.0.1/nginx_status
Check 3: Is stub_status module available?
nginx -V 2>&1 | grep http_stub_status_module
Check 4: Check agent configuration
cat /opt/statusradar/config/agent.yaml | grep -A3 nginx
Check 5: Check agent logs
sudo journalctl -u statusradar-agent -n 100 --no-pager | grep nginx
Common Errors
"Connection refused"
Error:
ERROR: Plugin nginx: Connection refused
Causes:
- Nginx not running
- Wrong URL in configuration
- stub_status not listening on expected address/port
Solution:
# Check if Nginx is running
sudo systemctl status nginx
# Check Nginx is listening on expected port
sudo netstat -tlnp | grep nginx
# Test URL manually
curl http://127.0.0.1/nginx_status
# Check Nginx configuration
sudo nginx -T | grep stub_status
"HTTP 404 Not Found"
Error:
ERROR: Plugin nginx: HTTP 404 Not Found
Cause: stub_status location not configured or wrong URL
Solution:
# Check Nginx configuration for stub_status
sudo nginx -T | grep -A5 stub_status
# Verify location path
# If configured as '/status', use: http://127.0.0.1/status
# If configured as '/nginx_status', use: http://127.0.0.1/nginx_status
Update agent configuration with correct URL:
plugins:
nginx:
status_url: http://127.0.0.1/nginx_status # Match your Nginx config
"HTTP 403 Forbidden"
Error:
ERROR: Plugin nginx: HTTP 403 Forbidden
Cause: IP address not allowed in Nginx configuration
Solution:
Edit Nginx configuration:
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1; # Add agent's IP address
deny all;
}
Reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
"stub_status module not available"
Error:
ERROR: Plugin nginx: stub_status not available
Cause: Nginx compiled without stub_status module
Solution:
Check if module is available:
nginx -V 2>&1 | grep http_stub_status_module
If not available, you need to:
- Install Nginx from official repository (includes module)
- Or recompile Nginx with
--with-http_stub_status_module
Install Nginx with stub_status (Ubuntu/Debian):
sudo apt-get update
sudo apt-get install nginx
Metrics Showing Unexpected Values
Symptom: Metrics don't match expectations
Debug:
# View raw stub_status output
curl http://127.0.0.1/nginx_status
# Check Nginx access log
sudo tail -f /var/log/nginx/access.log
# Check Nginx error log
sudo tail -f /var/log/nginx/error.log
# Check active workers
ps aux | grep nginx | grep worker
Performance Impact
On Nginx
Negligible impact:
- stub_status provides pre-calculated counters
- No additional processing overhead
- Response time < 1ms
- Zero impact on request handling
Benchmark:
- Nginx RPS with monitoring: 50,000+ RPS
- Nginx RPS without monitoring: 50,000+ RPS
- Overhead: 0%
On Agent
Resource usage:
- Memory: +5 MB
- CPU: +1% during collection (0.1-0.2 seconds)
- Network: +0.5 KB per collection
Use Cases
1. Connection Monitoring
Monitor:
- Active connections
- Connection accept rate
- Connection drop rate (accepts - handled)
Alert on:
- Active connections spike (DDoS?)
- Connection drops > 0 (resource exhaustion)
- Active connections > worker_connections limit
2. Request Rate Tracking
Monitor:
- Requests per second
- Request growth trends
- Request patterns (time of day)
Alert on:
- Sudden RPS drop (application issue)
- Unusual RPS spike
- RPS exceeds capacity
3. Worker State Analysis
Monitor:
- Reading/writing/waiting distribution
- Waiting connections ratio
- Worker efficiency
Alert on:
- High reading count (slow clients)
- High writing count (slow backend or large responses)
- All workers busy
4. Keep-Alive Optimization
Monitor:
- Waiting connections (keep-alive)
- Active vs waiting ratio
Optimize:
- Adjust
keepalive_timeout
- Adjust
keepalive_requests
- Balance connection reuse vs memory
Best Practices
1. Secure stub_status Endpoint
Always restrict access:
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow ::1;
deny all;
}
Never expose publicly:
# BAD - Don't do this!
location /nginx_status {
stub_status on;
# No access restrictions = security risk!
}
2. Disable Access Logging
stub_status generates frequent requests, no need to log them:
location /nginx_status {
stub_status on;
access_log off; # Important: reduces I/O
allow 127.0.0.1;
deny all;
}
3. Use Localhost for Local Monitoring
# Good - fast, secure
plugins:
nginx:
status_url: http://127.0.0.1/nginx_status
# Avoid - unnecessary network overhead
plugins:
nginx:
status_url: http://hostname.example.com/nginx_status
4. Monitor Connection Limits
Know your limits:
# Check worker connections
grep worker_connections /etc/nginx/nginx.conf
Example:
events {
worker_connections 1024; # Max connections per worker
}
With 4 workers: Max = 4 * 1024 = 4096 connections
Set alert: active_connections > 3000
(75% of max)
5. Optimize for Your Workload
For API servers (mostly JSON responses):
- Lower keepalive_timeout (10-30 seconds)
- Higher keepalive_requests (100+)
For static content:
- Higher keepalive_timeout (65 seconds)
- Standard keepalive_requests (100)
Advanced Configuration
Multiple Nginx Instances
To monitor multiple Nginx instances on same server:
Option 1: Different ports
Instance 1:
plugins:
nginx:
status_url: http://127.0.0.1:8080/nginx_status
Instance 2: Deploy separate agent.
Option 2: Different URLs
Not currently supported in single agent - use separate agents.
HTTPS Status Endpoint
server {
listen 127.0.0.1:443 ssl;
server_name localhost;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Agent configuration:
plugins:
nginx:
status_url: https://127.0.0.1/nginx_status
Custom Status Path
location /private/monitoring/nginx {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
Agent configuration:
plugins:
nginx:
status_url: http://127.0.0.1/private/monitoring/nginx
Example Configurations
Basic Web Server
# /etc/nginx/sites-available/default
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Reverse Proxy
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Load Balancer
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
server {
listen 80;
server_name lb.example.com;
location / {
proxy_pass http://backend;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Interpreting Metrics
Understanding Active Connections
Active connections = reading + writing + waiting
Example:
Active connections: 100
Reading: 5 Writing: 10 Waiting: 85
Interpretation:
- 100 total active connections
- 5 clients sending requests
- 10 clients receiving responses
- 85 idle keep-alive connections
Connection Statistics
server accepts handled requests
12345 12345 67890
Means:
- 12,345 accepted connections
- 12,345 handled connections (no drops)
- 67,890 total requests
- Average 5.5 requests per connection (67890 / 12345)
If accepts > handled:
- Some connections were dropped
- Possible causes: resource limits, configuration issues
Calculating Metrics
Requests per connection:
rpc = total_requests / total_handled_connections
High value = good keep-alive usage
Connection drop rate:
drop_rate = (accepts - handled) / accepts
Should be 0%
Next Steps
- Overview
- Requirements
- Nginx Version
- Python Dependencies
- Nginx Module
- Configuration
- Basic Configuration
- Custom Status URL
- Remote Nginx Server
- All Configuration Options
- Environment Variables
- Nginx Setup
- Enable stub_status Module
- Security Considerations
- Test Configuration
- Collected Metrics
- Connection Metrics
- Worker State Metrics
- Dashboard Metrics
- Overview Card
- Connection Chart
- Worker States Chart
- Request Rate Chart
- Installation
- Quick Install
- Install on Existing Agent
- Testing
- Manual Plugin Test
- Test stub_status Endpoint
- Troubleshooting
- Plugin Not Collecting Metrics
- Common Errors
- Metrics Showing Unexpected Values
- Performance Impact
- On Nginx
- On Agent
- Use Cases
- 1. Connection Monitoring
- 2. Request Rate Tracking
- 3. Worker State Analysis
- 4. Keep-Alive Optimization
- Best Practices
- 1. Secure stub_status Endpoint
- 2. Disable Access Logging
- 3. Use Localhost for Local Monitoring
- 4. Monitor Connection Limits
- 5. Optimize for Your Workload
- Advanced Configuration
- Multiple Nginx Instances
- HTTPS Status Endpoint
- Custom Status Path
- Example Configurations
- Basic Web Server
- Reverse Proxy
- Load Balancer
- Interpreting Metrics
- Understanding Active Connections
- Connection Statistics
- Calculating Metrics
- Next Steps