initial module
This commit is contained in:
92
docs/API.md
Normal file
92
docs/API.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# API
|
||||
|
||||
All JSON responses are compact, versioned, and timestamped.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"module": "1.0.0",
|
||||
"timestamp": 1710000000,
|
||||
"scope": "full"
|
||||
}
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
If `monitor_api_token` is set, non-dashboard endpoints require one of:
|
||||
|
||||
- `Authorization: Bearer <token>`
|
||||
- `X-Monitor-Token: <token>`
|
||||
- `?token=<token>`
|
||||
|
||||
If `monitor_basic_auth` is set to `user:password`, every monitoring endpoint requires HTTP Basic auth. For public production deployments, prefer terminating authentication at Nginx with `auth_basic` and `auth_basic_user_file`.
|
||||
|
||||
## JSON Endpoints
|
||||
|
||||
### `/monitor/api`
|
||||
|
||||
Returns all sections:
|
||||
|
||||
- `system`
|
||||
- `nginx`
|
||||
- `network`
|
||||
- `disk`
|
||||
- `processes`
|
||||
- `upstreams`
|
||||
- `connections`
|
||||
- `requests`
|
||||
- `history`
|
||||
|
||||
### `/monitor/api/system`
|
||||
|
||||
Includes:
|
||||
|
||||
- `cpu.usage`
|
||||
- `cpu.cores`
|
||||
- `cpu.load`
|
||||
- `memory.total`
|
||||
- `memory.available`
|
||||
- `memory.used`
|
||||
- `memory.used_pct`
|
||||
- `swap.total`
|
||||
- `swap.free`
|
||||
- `swap.used_pct`
|
||||
- `uptime`
|
||||
|
||||
### `/monitor/api/requests`
|
||||
|
||||
Includes:
|
||||
|
||||
- total request and response counters
|
||||
- request and response moving averages
|
||||
- status counters
|
||||
- method distribution
|
||||
- response size histogram
|
||||
- latency histogram
|
||||
- latency percentiles `p50`, `p90`, `p95`, `p99`
|
||||
- `top_urls`
|
||||
- `user_agents`
|
||||
|
||||
### `/monitor/live`
|
||||
|
||||
SSE stream:
|
||||
|
||||
```text
|
||||
retry: 3000
|
||||
: heartbeat 42
|
||||
id: 42
|
||||
event: metrics
|
||||
data: {"version":1,"timestamp":1710000000,...}
|
||||
```
|
||||
|
||||
The dashboard uses SSE first and falls back to polling `/monitor/api`.
|
||||
|
||||
### `/monitor/metrics`
|
||||
|
||||
Prometheus text format with core counters and gauges:
|
||||
|
||||
- `nginx_monitor_requests_total`
|
||||
- `nginx_monitor_active_connections`
|
||||
- `nginx_monitor_cpu_usage_ratio`
|
||||
- `nginx_monitor_memory_used_ratio`
|
||||
- `nginx_monitor_latency_p95_ms`
|
||||
60
docs/ARCHITECTURE.md
Normal file
60
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Architecture
|
||||
|
||||
## Request Path
|
||||
|
||||
The module registers two HTTP phase handlers:
|
||||
|
||||
- content phase: handles `/monitor`, `/monitor/api*`, `/monitor/live`, `/monitor/metrics`, and `/monitor/health`
|
||||
- log phase: accounts completed application requests
|
||||
|
||||
Monitoring endpoints are excluded from request accounting to avoid dashboard polling skewing the service metrics.
|
||||
|
||||
## Shared Memory
|
||||
|
||||
The module allocates one shared memory zone named `ngx_http_monitoring`. The zone contains:
|
||||
|
||||
- global request, response, connection, and system counters
|
||||
- fixed-size top URL and user-agent tables
|
||||
- fixed-size upstream peer table
|
||||
- per-worker metric slots keyed by `ngx_process_slot`
|
||||
- fixed-size historical ring buffer
|
||||
- collector lock and API rate-limit counters
|
||||
|
||||
Hot request-path updates use Nginx atomic operations. The shared slab mutex is used only for rare top-N slot creation or replacement and rate-limit window resets.
|
||||
|
||||
## Collection
|
||||
|
||||
Each worker owns a timer, but collection is guarded by an atomic shared lock, so only one worker performs a collection pass at a time. Collection reads:
|
||||
|
||||
- `/proc/stat`
|
||||
- `/proc/loadavg`
|
||||
- `/proc/meminfo`
|
||||
- `/proc/net/dev`
|
||||
- `/proc/diskstats`
|
||||
- `/proc/uptime`
|
||||
- `/proc/net/tcp`
|
||||
- `/proc/net/tcp6`
|
||||
- `/proc/net/sockstat`
|
||||
- `/proc/mounts`
|
||||
- `/proc/self/status`
|
||||
- `/proc`
|
||||
- `statvfs()`
|
||||
- `getifaddrs()`
|
||||
|
||||
The collector computes deltas and moving averages, then appends a sample to the ring buffer according to `monitor_resolution`.
|
||||
|
||||
## Serialization
|
||||
|
||||
JSON and Prometheus responses are generated from shared-memory snapshots only. API handlers do not read `/proc`, do not allocate persistent state, and use one request-pool buffer per response.
|
||||
|
||||
## SSE
|
||||
|
||||
`/monitor/live` is a long-lived request. Each client owns two reusable output buffers and a timer. The writer skips a tick if the connection still has pending buffered output, preventing slow clients from accumulating unbounded memory.
|
||||
|
||||
## Upstreams
|
||||
|
||||
Upstream metrics are passively observed from Nginx upstream state recorded on proxied requests. This avoids active backend probing in workers. Failures are counted from zero or `5xx` upstream statuses.
|
||||
|
||||
## Compatibility
|
||||
|
||||
The module is designed as an Nginx dynamic HTTP module and should be built with `--with-compat` against the target Nginx source tree. Stub-status counters are compiled in when the target Nginx build includes `--with-http_stub_status_module`; otherwise request counters still work but low-level active/reading/writing/waiting counters remain zero.
|
||||
51
docs/CONFIGURATION.md
Normal file
51
docs/CONFIGURATION.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Configuration
|
||||
|
||||
## Core
|
||||
|
||||
```nginx
|
||||
monitor on | off;
|
||||
monitor_dashboard on | off;
|
||||
monitor_api on | off;
|
||||
monitor_sse on | off;
|
||||
```
|
||||
|
||||
`monitor` can be used at `http`, `server`, or `location` scope. A prefix location is recommended:
|
||||
|
||||
```nginx
|
||||
location /monitor {
|
||||
monitor on;
|
||||
}
|
||||
```
|
||||
|
||||
## Collection
|
||||
|
||||
```nginx
|
||||
monitor_refresh_interval 1s;
|
||||
monitor_history 5m;
|
||||
monitor_resolution 1s;
|
||||
monitor_shm_size 8m;
|
||||
monitor_collect_system on;
|
||||
monitor_collect_nginx on;
|
||||
monitor_collect_network on;
|
||||
monitor_access_log on;
|
||||
monitor_max_top_urls 100;
|
||||
```
|
||||
|
||||
`monitor_history / monitor_resolution` is capped by the compiled maximum of 3600 samples.
|
||||
|
||||
## Security
|
||||
|
||||
```nginx
|
||||
monitor_allow 10.0.0.0/8;
|
||||
monitor_allow 127.0.0.1/32;
|
||||
monitor_deny all;
|
||||
|
||||
monitor_basic_auth off;
|
||||
monitor_api_token "change-me";
|
||||
monitor_rate_limit 120;
|
||||
monitor_cors off;
|
||||
```
|
||||
|
||||
ACL rules are evaluated in order. `monitor_basic_auth` accepts `off` or a literal `user:password`. For strong password storage, use Nginx `auth_basic` in the same location instead.
|
||||
|
||||
`monitor_cors` accepts `off`, `*`, or a literal origin such as `https://ops.example.com`.
|
||||
48
docs/PERFORMANCE.md
Normal file
48
docs/PERFORMANCE.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Performance
|
||||
|
||||
## Hot Path
|
||||
|
||||
The log-phase request accounting path performs:
|
||||
|
||||
- one timestamp delta calculation
|
||||
- atomic increments for request, status, method, latency, and size buckets
|
||||
- one bounded top-URL table update
|
||||
- optional user-agent and upstream updates
|
||||
|
||||
Top-N table insertion or replacement takes the shared slab mutex, but existing entries update with atomics only.
|
||||
|
||||
## Collector Cost
|
||||
|
||||
Collectors run from Nginx timers at `monitor_refresh_interval`. API requests do not trigger collection. Default collection is once per second.
|
||||
|
||||
For very large hosts, `/proc/net/tcp` and `/proc/net/tcp6` can be expensive because they scale with connection count. If needed, increase `monitor_refresh_interval` or disable system collection:
|
||||
|
||||
```nginx
|
||||
monitor_collect_system off;
|
||||
```
|
||||
|
||||
## Memory
|
||||
|
||||
Default shared memory is 8 MiB:
|
||||
|
||||
```nginx
|
||||
monitor_shm_size 8m;
|
||||
```
|
||||
|
||||
The default fixed-size structures are bounded:
|
||||
|
||||
- history samples: 3600 maximum
|
||||
- top URLs: 256 maximum
|
||||
- user agents: 64 maximum
|
||||
- upstream peers: 128 maximum
|
||||
- workers: 128 maximum
|
||||
- interfaces, disks, filesystems: 32 each
|
||||
|
||||
## Operational Guidance
|
||||
|
||||
- Build with `--with-compat`.
|
||||
- Build with `--with-http_stub_status_module` for exact Nginx connection counters.
|
||||
- Keep dashboard access private with `monitor_allow` / `monitor_deny` or standard Nginx auth modules.
|
||||
- Use `monitor_api_token` when exposing API or SSE across trust boundaries.
|
||||
- Put `/monitor` behind an internal listener or VPN for production.
|
||||
- Keep `monitor_resolution` at `1s` or higher on very busy systems.
|
||||
Reference in New Issue
Block a user