This commit is contained in:
Mateusz Gruszczyński committed 2026-11-10 18:05:00 +01:00
1 parent 643999f17e
commit 668c908abb
18 files changed
+13 -2

No files matched your search

+3 -1
View File
@@ -4,9 +4,11 @@ Release history focused on **features, settings, default behavior, compatibility
## 0.36.11 — more Backends metrics ## 0.36.11 — more Backends metrics
- **Backends overview — new columns:** seven more metrics, each sortable and switchable under **Columns**, fill the empty space of wide screens. **HTTP codes** (on by default) shows the 2xx share, any 4xx/5xx shares and a stacked 2xx/3xx/4xx/5xx bar. **Cache** (on by default) shows a HIT-ratio ring and how many bytes were served from cache versus fetched from the backend (ORIGIN); the tooltip lists HIT/MISS/BYPASS counts. **Req/s** shows the current request rate of the backend. **p95 / p99** shows latency percentiles, read from the latency histogram (shown as the bucket's upper bound; above 5 s is shown as ">5 s"). **Probe** shows the last active health-check latency and how long ago it ran. **Error causes** shows up to three most frequent failure counters (5xx, timeout, connect, TLS, DNS, I/O, queue, limit, retry). **Protocol** shows the last observed upstream protocol (H1/H2) and the HTTP/2 share. HTTP codes, Cache and p95 / p99 are counted per vhost, so all backends of one vhost show the same value. The vhosts panel backend table offers the same columns as text. - **Backends overview — new columns:** seven more metrics, each sortable and switchable under **Columns**, fill the empty space of wide screens. **HTTP codes** (on by default) shows the 2xx share, any 4xx/5xx shares and a stacked 2xx/3xx/4xx/5xx bar. **Cache** (on by default) shows a HIT-ratio ring, the response bytes served from the vhost's cache (CACHE) and the response bytes this backend delivered (ORIGIN); the tooltip lists HIT/MISS/BYPASS counts. **Req/s** shows the current request rate of the backend. **p95 / p99** shows latency percentiles, read from the latency histogram (shown as the bucket's upper bound; above 5 s is shown as ">5 s"). **Probe** shows the last active health-check latency and how long ago it ran. **Error causes** shows up to three most frequent failure counters (5xx, timeout, connect, TLS, DNS, I/O, queue, limit, retry). **Protocol** shows the last observed upstream protocol (H1/H2) and the HTTP/2 share. HTTP codes, Cache and p95 / p99 are counted per vhost, so all backends of one vhost show the same value. The vhosts panel backend table offers the same columns as text.
- **Status API:** each `vhost_metrics` entry in `GET /api/status` (full and `view=live`) adds `status_classes` (1xx–5xx counters), `p95_latency_ms` and `p99_latency_ms` (`null` without traffic). A new top-level `vhost_cache_totals` object (vhost ID → `hits`, `misses`, `bypasses`, `saved_body_bytes`) sums the cache domain statistics per vhost. - **Status API:** each `vhost_metrics` entry in `GET /api/status` (full and `view=live`) adds `status_classes` (1xx–5xx counters), `p95_latency_ms` and `p99_latency_ms` (`null` without traffic). A new top-level `vhost_cache_totals` object (vhost ID → `hits`, `misses`, `bypasses`, `saved_body_bytes`) sums the cache domain statistics per vhost.
- **Preferences API:** `backend_table_columns` and `backend_table_sort` accept `rate`, `statuses`, `p95`, `cache`, `probe`, `causes` and `protocol`. The default column set adds `statuses` and `cache`; the other new columns are opt-in. - **Preferences API:** `backend_table_columns` and `backend_table_sort` accept `rate`, `statuses`, `p95`, `cache`, `probe`, `causes` and `protocol`. The default column set adds `statuses` and `cache`; the other new columns are opt-in.
- **Info popovers:** the "i" explanations (for example next to Response time history) were drawn as one long line running past the card when they sat in a single-line chart header; they now wrap inside the popover.
- **Documentation:** refreshed screenshots (dark theme, 90% scale, interface icons, collapsed menu, colour-blind safe charts) and a new Backends card screenshot in the screenshot tour.
- **Upgrade notes:** no configuration or database migration is required. An account that has already saved its own column choice keeps it, so enable the new columns under **Columns** in the Backends card. - **Upgrade notes:** no configuration or database migration is required. An account that has already saved its own column choice keeps it, so enable the new columns under **Columns** in the Backends card.
## 0.36.10 — Fit to screen, collapsible menu and smoother startup ## 0.36.10 — Fit to screen, collapsible menu and smoother startup
+6
View File
@@ -2,6 +2,8 @@
A tour of the RustProxy administration panel. The panel runs on the separate administration listener (by default `http://127.0.0.1:9090`) and is available in English and Polish, with light and dark themes. A tour of the RustProxy administration panel. The panel runs on the separate administration listener (by default `http://127.0.0.1:9090`) and is available in English and Polish, with light and dark themes.
The screenshots show demo data with the dark theme, 90% interface scale, SVG interface icons, the collapsed left menu and the colour-blind safe chart palette.
## Sign-in ## Sign-in
Local administrator sign-in. The first account is created with a one-time setup token; there is no default password. Local administrator sign-in. The first account is created with a one-time setup token; there is no default password.
@@ -14,6 +16,10 @@ Live requests per second, bandwidth, status codes, cache hit ratio, protocol mix
![Overview dashboard](images/overview.png) ![Overview dashboard](images/overview.png)
The Backends card lists every backend with request rate, HTTP status classes, latency trend, p95/p99, health probe, cache HIT ratio with cache/origin bytes, traffic and the last event. Columns can be chosen under **Columns**.
![Backends card](images/overview-backends.png)
## Vhosts ## Vhosts
Every published domain with its listeners, backends, health, request rate and security options. The editor groups frontend, backends, balancing, security, cache and custom locations. Every published domain with its listeners, backends, health, request rate and security options. The editor groups frontend, backends, balancing, security, cache and custom locations.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 KiB

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 KiB

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 112 KiB

+3
View File
@@ -1324,6 +1324,9 @@ html[data-interface-icons="true"] .network-interface-hidden .quiet>svg.ui-icon {
border-radius: var(--rp-radius-surface, 6px); border-radius: var(--rp-radius-surface, 6px);
background: var(--panel2); background: var(--panel2);
box-shadow: 0 12px 30px var(--shadow-mid); box-shadow: 0 12px 30px var(--shadow-mid);
white-space: normal;
text-align: left;
overflow-wrap: break-word;
} }
.metric-info-popover .fine { .metric-info-popover .fine {
+1 -1
View File
@@ -297,7 +297,7 @@ function backendExtraMetrics(pool, member, status, snapshot, now, seen) {
const classes = Array.isArray(vhost.status_classes) ? vhost.status_classes.map(value => Math.max(0, Number(value) || 0)) : [0, 0, 0, 0, 0]; const classes = Array.isArray(vhost.status_classes) ? vhost.status_classes.map(value => Math.max(0, Number(value) || 0)) : [0, 0, 0, 0, 0];
const classTotal = classes.reduce((sum, value) => sum + value, 0); const classTotal = classes.reduce((sum, value) => sum + value, 0);
const hits = Number(cacheTotals?.hits) || 0, misses = Number(cacheTotals?.misses) || 0, bypasses = Number(cacheTotals?.bypasses) || 0, lookups = hits + misses + bypasses; const hits = Number(cacheTotals?.hits) || 0, misses = Number(cacheTotals?.misses) || 0, bypasses = Number(cacheTotals?.bypasses) || 0, lookups = hits + misses + bypasses;
const cacheBytes = Math.max(0, Number(cacheTotals?.saved_body_bytes) || 0), outBytes = Math.max(cacheBytes, Number(vhost.bytes_out) || 0), originBytes = Math.max(0, outBytes - cacheBytes); const cacheBytes = Math.max(0, Number(cacheTotals?.saved_body_bytes) || 0), originBytes = Math.max(0, Number(member.bytes_out) || 0), outBytes = cacheBytes + originBytes;
const p95 = Number(vhost.p95_latency_ms) || 0, p99 = Number(vhost.p99_latency_ms) || 0; const p95 = Number(vhost.p95_latency_ms) || 0, p99 = Number(vhost.p99_latency_ms) || 0;
const probeOff = member.health_mode === "off", probeLatency = Number(member.latency_ms) || 0, probeAt = Number(member.last_probe_ms) || 0; const probeOff = member.health_mode === "off", probeLatency = Number(member.latency_ms) || 0, probeAt = Number(member.last_probe_ms) || 0;
const causes = BO_CAUSES.map(([field, label]) => ({ label, value: Math.max(0, Number(member[field]) || 0) })).filter(cause => cause.value > 0).sort((a, b) => b.value - a.value); const causes = BO_CAUSES.map(([field, label]) => ({ label, value: Math.max(0, Number(member[field]) || 0) })).filter(cause => cause.value > 0).sort((a, b) => b.value - a.value);