This commit is contained in:
Mateusz Gruszczyński committed 2026-10-15 09:37:47 +02:00
1 parent bbfa8cbc3f
commit 2ccc598b12
49 files changed
+4771 -639

No files matched your search

+51
View File
@@ -56,6 +56,57 @@ Only `GET` on the exact configured path without a query string is accepted. A
wrong path is `404`, wrong method `405`, disallowed peer `403`, invalid/missing
required bearer `401`, and exporter concurrency exhaustion `429`.
## Web Server and PHP-FPM metrics (0.33.0)
Prometheus already exports core Web Server/PHP response counters by configured
`web_service` ID. The 0.33.0 additions below are enabled with the existing
Prometheus exporter (no new listener, credentials, options or open routes).
| Family | Type | Labels | Meaning |
|---|---|---|---|
| `rust_proxy_web_server_requests_total` | counter | `web_service` | Header-ready WWW responses, including PHP |
| `rust_proxy_web_server_responses_total` | counter | `web_service`, `class` | HTTP 2xx/3xx/4xx/5xx |
| `rust_proxy_web_server_response_header_duration_microseconds_total` | counter | `web_service` | Cumulative time until headers |
| `rust_proxy_web_server_requests_active` | gauge | `web_service` | Requests still awaiting headers |
| `rust_proxy_web_server_request_kind_total` | counter | `web_service`, `kind` | `static`, `php`, `other` handler |
| `rust_proxy_web_server_methods_total` | counter | `web_service`, `method` | `GET`, `POST`, `PUT`, `DELETE`, `other` |
| `rust_proxy_web_server_status_code_total` | counter | `web_service`, `status` | Selected 200/206/304/403/404/500/502/503 |
| `rust_proxy_web_server_response_body_bytes_total` | counter | `web_service` | Body bytes delivered before final compression |
| `rust_proxy_web_server_compression_total` | counter | `web_service`, `encoding` | Downstream gzip/br/zstd/deflate operations |
| `rust_proxy_php_requests_total` | counter | `web_service` | PHP response headers processed |
| `rust_proxy_php_responses_total` | counter | `web_service`, `class` | PHP response status classes |
| `rust_proxy_php_response_header_duration_microseconds_total` | counter | `web_service` | Cumulative PHP time until headers |
| `rust_proxy_php_response_body_bytes_total` | counter | `web_service` | PHP body bytes emitted before compression |
| `rust_proxy_php_concurrency_available` | gauge | `web_service` | Free RustProxy PHP request permits |
| `rust_proxy_php_concurrency_limit` | gauge | `web_service` | Configured concurrent PHP request limit |
| `rust_proxy_php_concurrency_in_use` | gauge | `web_service` | Permits currently held by PHP requests |
| `rust_proxy_php_failures_total` | counter | `web_service`, `reason` | Fixed FastCGI/PHP failure classes |
PHP `reason` is one of `capacity`, `connect_timeout`, `connect_error`,
`request_timeout`, `request_io`, `response_timeout`, `response_io`,
`invalid_response`, `body_io`. PHP concurrency is the admission semaphore in
RustProxy, not external PHP worker health or PHP-FPM child count. Status-code
labels are deliberately restricted to a stable, useful subset; arbitrary code,
request paths, IP addresses and untrusted method strings are not labels.
The exported byte counters are measured **before the final dynamic response
encoder**, so treat them as payload sizes rather than measured network transfer.
Precompressed static file delivery is not counted in the downstream compression
family. All time-to-headers metrics exclude streamed transfer duration.
Useful Grafana/PromQL examples:
```promql
sum(rate(rust_proxy_web_server_requests_total[5m]))
sum by (class) (rate(rust_proxy_web_server_responses_total[5m]))
sum by (kind) (rate(rust_proxy_web_server_request_kind_total[5m]))
100 * sum(rust_proxy_php_concurrency_in_use) / clamp_min(sum(rust_proxy_php_concurrency_limit), 1)
1e-3 * sum(rate(rust_proxy_web_server_response_header_duration_microseconds_total[5m])) / clamp_min(sum(rate(rust_proxy_web_server_requests_total[5m])), 1e-9)
sum by (reason) (rate(rust_proxy_php_failures_total[5m]))
```
Import `grafana/rustproxy-overview.json` and use the **Web service** variable
for the new Web Server, PHP-FPM, per-service and correlation sections.
## Coverage audit in 0.26.0
The exporter represents all scalar fields currently sampled by `diagnostics::View` when available. The per-interface `network_interfaces` list added in 0.18.6 is intentionally dashboard-only so kernel-created interface names cannot create an uncontrolled Prometheus label set. RustProxy also exports the bounded operational data already available from traffic metrics, cache, vhosts, backend pools, streams, logging, GeoIP and ACME renewal observations.
-20
View File
@@ -19,7 +19,6 @@ Current direction: 0.24.10 -> 0.25.0
- [x] Add unit/source-contract coverage, OpenAPI/UI language coverage and Web Server documentation.
- [x] Clean 0.25 README/Docs/CHANGELOG release material so current user-facing changes are separated from historical audits.
- [x] Add an authenticated `/docs` Markdown Reader with a separate API/OpenAPI tab, canonical docs index, 0.25 specification audit and open-work TODO.
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` plus live H1/H2/H3/static-file acceptance on the release host.
## 0.24.10
@@ -29,7 +28,6 @@ Current direction: 0.24.9 -> 0.24.10
- [x] Remove the redundant Error File help sentence while retaining JSON/RAW controls and live apply.
- [x] Keep response-time history permanently expanded and add an accessible information popover matching Process.
- [x] Extend UI/API/source regressions and update release identity to 0.24.10.
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and browser acceptance on the release host.
## 0.24.9
@@ -39,7 +37,6 @@ Current direction: 0.24.8 -> 0.24.9
- [x] Add password-encrypted full backup/restore with manifest validation, integrity checks, staging and rollback-safe activation.
- [x] Add the optional bounded asynchronous ERROR file sink with JSON/RAW formats, shared secret redaction and external logrotate integration.
- [x] Extend offline source/release contracts and update release identity to 0.24.9.
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and end-to-end backup/restore/error-log acceptance on the release host.
## 0.24.8
@@ -63,7 +60,6 @@ Current direction: 0.24.6 -> 0.24.7
- [x] Clean externally reported cache/CSS compiler warnings without lint suppression.
- [x] Rotate cache compatibility identity for global transform representation/eligibility changes but not resource-only capacity metadata.
- [x] Extend OpenAPI, SQLite persistence, memory-contract and release/source regressions and update release identity to 0.24.7.
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and sustained RSS/heap acceptance for every resource preset on the release host.
## 0.24.6
@@ -75,7 +71,6 @@ Current direction: 0.24.5 -> 0.24.6
- [x] Bound stale revalidation, proactive refresh scheduling, COLD cleanup selection/concurrency and delete fallback tasks.
- [x] Audit the remaining long-lived/background workers for queue/task cardinality and cancellation ownership.
- [x] Add Rust-independent memory contract regression checks and update release identity to 0.24.6.
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and sustained RSS/heap acceptance on the release host.
## 0.24.5
@@ -89,7 +84,6 @@ Current direction: 0.24.4 -> 0.24.5
- [x] Make global cache disable authoritative over vhost overrides and remove the artificial 1 GiB HOT/object ceiling.
- [x] Add host/cgroup-aware conservative/recommended/performance cache presets and non-blocking memory/headroom warnings in Settings.
- [x] Update source/package/UI/OpenAPI identity and offline release checks to 0.24.5.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, the H1/H2/H3 method matrix, and cache RSS/HOT/COLD stress acceptance on the release host.
## 0.24.4
@@ -98,7 +92,6 @@ Current direction: 0.24.3 -> 0.24.4
- [x] Make the Linux THP mitigation process-local with `PR_SET_THP_DISABLE` before Tokio worker creation.
- [x] Preserve the existing glibc arena limit and allocator-trim behavior.
- [x] Add source/release regression coverage for THP opt-out ordering and release identity.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and a sustained production RSS comparison with host THP returned to its normal policy.
## 0.24.3
@@ -110,7 +103,6 @@ Current direction: 0.24.2 -> 0.24.3
- [x] Rename Proxy Process to Process and hide unsupported platform diagnostics dynamically.
- [x] Remove the stale unreferenced per-BSD parser source from the release archive.
- [x] Update source/package/UI/OpenAPI identity and Rust-independent release gates to 0.24.3.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and sustained cache/transform RSS acceptance on the release host.
## 0.24.2
@@ -132,7 +124,6 @@ Current direction: 0.24.0 -> 0.24.1
- [x] Remove artificial hostname-count ceilings from certificate bindings/issuance and hostname-list configuration while retaining syntax, payload and resource-safety bounds.
- [x] Update source/package/UI/OpenAPI identity and source-side regression contracts to 0.24.1.
- [ ] Generate and commit a resolver-produced `Cargo.lock`, then run compiler-enabled `cargo fmt --all`, `cargo check --locked --all-targets` and `cargo test --locked --all-targets` on the release host.
- [ ] Run native FreeBSD/OpenBSD/NetBSD diagnostics acceptance and final H2/H3/WebSocket/proxy-statistics regression.
The 0.24.1-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -159,7 +150,6 @@ Current direction: 0.23.2 -> 0.23.3
- [x] Tolerate old `101` response framing while keeping the WebSocket accept proof and subprotocol validation strict.
- [x] Add dashboard/OpenAPI/language-pack controls and source regressions.
- [x] Update package/source identity and Rust-independent release gates to 0.23.3.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and live iLO4/legacy WebSocket acceptance on the release host.
The 0.23.3-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -172,7 +162,6 @@ Current direction: 0.23.1 -> 0.23.2
- [x] Fix local CLI administration transport detection so HTTPS administration no longer traps `--livelogs` in a 308 reconnect loop.
- [x] Pin local CLI HTTPS to certificates from the private RustProxy certificate directory and reuse the transport for config/TLS CLI calls.
- [x] Update package/source identity and Rust-independent release gates to 0.23.2.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and live HTTPS `--livelogs` acceptance on the release host.
The 0.23.2-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -185,7 +174,6 @@ Current direction: 0.23.0 -> 0.23.1
- [x] Plot selected-scope Transform applied/cache-HIT/skipped/error rates from the existing runtime metrics endpoint.
- [x] Reuse the dashboard SVG/chart styling, live 3-second refresh and language-pack model.
- [x] Update package/source identity and Rust-independent release gates to 0.23.1.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and browser acceptance with sustained Cache/Transform traffic on the release host.
The 0.23.1-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -198,8 +186,6 @@ Current direction: 0.22.3 -> 0.23.0
- [x] Add Settings → Certificate API UX and preserve direct production binary commands for local deploy/reload.
- [x] Add `rust-proxy --livelogs` with a bounded live stream, interactive structured filters, detailed request inspection and explicit lag reporting.
- [x] Split Settings → Cache into General, Resilience, Cold cache and Static & diagnostics sub-tabs without changing the atomic cache settings document.
- [ ] Run compiler-enabled `rust-proxy`/Cargo check, tests and release build plus live token-auth certificate rotation and sustained high-rate live-log acceptance on the release host.
- [ ] Upstream mTLS/client certificate remains deliberately deferred.
The 0.23.0-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -213,8 +199,6 @@ Current direction: 0.22.2 -> 0.22.3
- [x] Add dedicated certificate hot reload without mutating desired configuration or revision.
- [x] Add external certificate deployment for Certbot/manual issuers with immutable generation staging and atomic multi-vhost switch by certificate id.
- [x] Add API/CLI/panel support plus audit/OpenAPI/documentation for certificate reload/deploy.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and live H1 -> h2c Upgrade -> H2 plus TLS/H2/H3 certificate-rotation acceptance on the release host.
- [ ] Upstream mTLS/client certificate remains deliberately deferred.
The 0.22.3-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -228,8 +212,6 @@ Current direction: 0.22.1 -> 0.22.2
- [x] Add detailed upstream failure classification plus last failure and health ejection/recovery timestamps.
- [x] Consolidate backend operations data in the existing dashboard table: health, active/limit, requests/errors, latency, traffic, last failure and last recovery.
- [x] Parse and expose public-certificate issuer/SAN/validity/remaining-days/expiry status plus renewal status/last attempt/error.
- [ ] Add a distinct maximum TCP connection/socket limit per backend; request concurrency is implemented but is intentionally not presented as a socket limit.
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test` and live H1/H2/H3 plus H2 -> proxy -> H2 acceptance on the release host.
The 0.22.2-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -245,7 +227,6 @@ Current direction: 0.22.0 -> 0.22.1
- [x] Split WebSocket tunnel statistics by H1 / H2 RFC 8441 / H3 RFC 9220 on the main dashboard and Prometheus.
- [x] Preserve the 0.22.0 cache feature set and `Accept-Ranges` policy.
- [x] Update 0.22.1 source/package identity and Rust-independent release gates.
- [ ] Run the compiler-enabled `./dev.sh check` / `./dev.sh test` gate plus live H1/H2/H3/h2c/RFC8441 acceptance on the release host.
The 0.22.1-era notes are summarized in the retained [technical changelog archive](CHANGELOG_TECHNICAL_ARCHIVE.md).
@@ -260,7 +241,6 @@ Current direction: 0.20.0 -> 0.21.0
- [x] Make Passive Backend Health explicit opt-in for ordinary and Docker vhosts while preserving independent active health checks and unconditional observability.
- [x] Keep route cache override tri-state and expose effective route/cache/transform diagnostics.
- [x] Close 0.21.0 with the current conservative JS/CSS transformers; defer parser-backed replacements to a later development cycle.
- [ ] Release-host gate: run Rust 1.88+ fmt/check/test/clippy/release-build and live H1/H2/H3/cache/compression/restart acceptance before deployment.
- [x] Finish release polish: backend timing header rename, human-readable uptime, transformed Live traffic series, Docker Passive Backend Health layout fix, warning cleanup and cache module split.
- [x] Keep package/source identity and OpenAPI at 0.21.0 and package the completed feature scope as the 0.21.0 release source.
-88
View File
@@ -1,88 +0,0 @@
# RustProxy 0.32.8 - verification report
## Scope
UI-only Overview header/editor button alignment, deletion of the complete
`tools/checks/` source directory, retained source-upgrade preflight and the
0.32.8 version bump. No proxy request path, backend behavior, preferences
schema or dashboard JavaScript event handlers were changed.
## Checks performed
- **PASS** - Chromium headless checked the actual Overview HTML and CSS at
viewport widths 320, 360, 375, 390, 430, 480, 600, 700, 768, 1024 and
1440 px, with Normal and Compact button styles and four visibility/editing
scenarios: 88 combinations. Title stays left, available actions align right;
no overlapping buttons or page/header horizontal overflow was observed.
This is a layout fixture, not a running API/backend acceptance test.
- **PASS** - All Overview and editor controls use the original semantic
`quiet`, `outline` and `primary` classes. No CSS class names were added.
Removed obsolete dedicated button selectors. The Overview/core/refresh/layout
JavaScript files are byte-identical to 0.32.7, so existing event handling,
save/cancel and editor locking implementations were not changed.
- **PASS** - Before removing the old QA directory, the 0.32.7 UI simulation
suites `dashboard_layout_editor_0323_ui_test.mjs` and
`dashboard_inline_layout_0323_ui_test.mjs` passed. The original
`appearance_density_buttons_0327.py` source check also passed. These tests
exercised simulated UI behavior, not a live RustProxy server.
- **PASS** - `python3 scripts/preflight.py`, `./dev.sh doctor`,
`./dev.sh repair`, shell syntax of `dev.sh` and the dependency-resolution
script, all bundled language JSON files, version consistency and source
class/handler comparisons.
- **PASS** - Source-upgrade rehearsal from the supplied 0.32.7 release tree
to 0.32.8 removed `tools/checks/` from the installed working tree, retained
the previous sources under `.upgrade-backup/`, preserved `.env` and left
`./dev.sh doctor` working. No live server/database was used in this rehearsal.
- **PASS** - All eight bundled SQL migration scripts applied twice in an
in-memory SQLite database; `PRAGMA integrity_check` returned `ok`.
## Limits and outstanding acceptance
- Rust/Cargo was **not available** in the verification environment, so
`./dev.sh check`, `./dev.sh test`, binary build and live proxy/UI regression
checks were not run. These remain required before production acceptance.
- An unrelated legacy `dashboard_startup_0310_ui_test.mjs` assertion was already
failing on the supplied 0.32.7 tree due to its expected
`prefers-reduced-motion: reduce` CSS rule being absent. That test was removed
with `tools/checks/`, not claimed as passing or fixed by this patch.
- The intentionally removed `tools/checks/` suites are no longer executed by
`dev.sh`; `./dev.sh test` now runs Cargo validation and the Rust test suite.
Independent API, stress, browser and real-runtime acceptance tests must be
run externally when required.
## Test-suite maintenance follow-up (0.32.8)
This maintenance change affects test code and duplicate test helpers only. No
production Rust or Go source logic was changed.
- Renamed the invalid Rust test identifier beginning with `304_` to
`response_304_with_private_policy_discards_cached_representation`. The
revalidation regression itself is retained.
- Placed four passive-health regression tests back inside the existing
`src/balance/tests.rs` `mod tests` scope, so they can use its private
`settings(HealthMode)` fixture. No test assertions were removed.
- Removed two byte-for-byte duplicate files under `scripts/tests/`:
`test_stream_tcp.py` and `test_stream_udp.py`. The canonical scripts under
`scripts/` remain, including their documented commands and self-tests.
- Statically enumerated 655 Rust `#[test]`/`#[tokio::test]` cases after the
edit, without duplicate test names or remaining numeric-leading test names.
A name containing an old version or `legacy` is not evidence that its
compatibility/regression coverage is obsolete.
**Checks passing in the available environment:**
- `python3 scripts/preflight.py`, `bash dev.sh doctor`, `bash dev.sh repair`.
- `go test ./...` in `docker-agent/`.
- `python3 scripts/test_stream_tcp.py selftest` and
`python3 scripts/test_stream_udp.py selftest` (mock-peer harness checks only;
these do not exercise RustProxy).
- Python AST parsing of all 14 scripts under `scripts/`, shell syntax checks
for `dev.sh` and the Stream/dependency helper scripts.
- All eight bundled SQLite migrations executed twice in order on an in-memory
database, with `PRAGMA integrity_check = ok` after both passes.
**Not verified:** The environment does not have `cargo` or `rustc`, and DNS
resolution is unavailable for downloading a toolchain. Consequently,
`cargo check --locked --all-targets` and `cargo test --locked --all-targets`
have not passed here. This maintenance does not close the live-runtime
acceptance gate or establish that every remaining test is passing.
+68
View File
@@ -20,6 +20,74 @@ A Web Service can be reused by several vhosts and one vhost can mix Web Server a
The Web Server implementation is split under `src/web_server/` by responsibility. `mod.rs` is only the public facade; `config.rs` owns persisted/compiled service configuration, `filesystem.rs` owns document-root confinement and directory reads, `security.rs` owns Web Service hardening, `response.rs` owns static HTTP response/validator/range/listing behavior, `routing.rs` owns rewrites/`try_files`/precompressed selection, `fastcgi.rs` owns PHP-FPM/FastCGI, `serve.rs` owns request dispatch, and `htaccess.rs` owns the compatibility layer. Regression tests live in `tests.rs`. This keeps filesystem/security and FastCGI changes reviewable without growing another single Web Server source file.
## Live Web Service diagnostics (0.33.0)
Each configured Web Service card now contains an **expandable Live metrics**
section with completed requests, responses/s, HTTP 5xx count, mean elapsed time
until response headers, PHP request permits in use/limit, static/PHP/other response
counts, delivered response body bytes and a compact per-service rate history.
The section reuses the existing authenticated live status stream and is closed
by default. Unconfigured/non-PHP services do not claim PHP worker capacity.
**Overview** provides 12 additional opt-in Web Server blocks under
**Settings -> Appearance -> Dashboard layout -> Overview cards**. All 12 are
hidden by default, including when opening an older saved dashboard layout.
They follow normal widget reordering, theme, card sizing and SSE updates.
Sample history length is selectable as 60/120/300/600 points (temporary or
browser-persistent), independently of Cache and Transform.
The authenticated `/api/status` and compact `/api/status?view=live` payloads
include `web_server_metrics`, keyed only by *configured Web Service ID*:
```json
{
"web_server_metrics": {
"site": {
"web": {
"requests": 120, "status_2xx": 100, "status_3xx": 5,
"status_4xx": 12, "status_5xx": 3,
"static_requests": 90, "php_requests": 25, "other_requests": 5,
"response_headers_us": 1500000, "response_bytes": 98000,
"active_headers": 0,
"methods": [110, 8, 0, 0, 2],
"selected_status": [95, 1, 3, 4, 8, 0, 2, 1],
"failures": [0, 0, 0, 0, 0, 0, 0, 0, 0],
"compression": [12, 1, 0, 0]
},
"php": {
"metrics": {
"requests": 25, "response_headers_us": 750000,
"response_bytes": 24000,
"failures": [0, 0, 0, 0, 0, 0, 0, 0, 0]
},
"capacity_limit": 32, "capacity_available": 24,
"capacity_used": 8
}
}
}
}
```
The example is illustrative; the actual `php` object is `null` when PHP is
not configured. Array orders: methods `GET, POST, PUT, DELETE, other`;
selected statuses `200, 206, 304, 403, 404, 500, 502, 503`;
FastCGI failures `capacity, connect_timeout, connect_error, request_timeout,
request_io, response_timeout, response_io, invalid_response, body_io`;
compression `gzip, br, zstd, deflate`.
**Accounting semantics:** The response-kind counters describe the handler
that produced the response; `other` covers early rejections not dispatched
to a static file or PHP. `active_headers` means requests still awaiting their
response headers, *not* live streaming body counts. Mean duration is until
response headers are ready. Body-byte counters advance only when body frames
are polled, **before final dynamic compression**; these are not network wire
bytes. The compression counter records only the downstream encoder, not static
precompressed `.gz`/`.br` sidecar selection. Failed PHP requests may count as
both PHP responses and FastCGI failures. PHP permit capacity is RustProxy's
configured request semaphore, *not* the number of processes in the external
PHP-FPM pool. All counters are process/snapshot lifetime observations and may
restart on a config publication.
## Dashboard configuration
The Web Service editor is split into stable configuration tabs so later features do not create one long form: