Add pkg/metrics/text, a small Prometheus text-format writer, and use it
for frpc's /metrics. The endpoint lives only on metricsServer and is
covered by its Basic Auth, like the other endpoints there.
The package emits the Go runtime families and, on Linux, the process
families read from /proc. Their names, types and help strings match
client_golang's default collectors, so existing Go runtime dashboards
keep working. It deliberately emits no frp_ business metrics and none of
client_golang's promhttp_ handler metrics.
Writing the subset ourselves keeps client_golang and protobuf out of the
frpc binary; both are still used by frps and by the tests here.
Add a separate HTTP listener for observability, configured through
metricsServer in both frps and frpc. It serves /healthz and, when
pprofEnable is set, the pprof handlers except /debug/pprof/cmdline. It
never serves the dashboard, static assets or the admin API, and it does
not touch the global assets filesystem.
frps also serves /metrics on this listener with both runtime and business
metrics, enabled by metricsServer.port alone. The in-memory collector
still starts only with the dashboard, and the Prometheus collector starts
either with metricsServer or with enablePrometheus plus webServer, so a
configuration that collected nothing before still collects nothing.
The /healthz, /metrics and pprof endpoints on webServer, and
enablePrometheus, keep working but are deprecated and log a hint at
startup. frpc does not serve /metrics yet.
When bandwidthLimitMode is "server", the work connection is wrapped by
libio.WrapReadWriteCloser with a close callback that captured the
variable being reassigned (local/rwc). At call time the callback
referenced the wrapper itself, whose closed guard was already set, so
Close returned nil without closing the underlying work connection.
For TCP proxies this left libio.Join blocked on the other copy
goroutine after the user disconnected, keeping the work connection and
the backend connection open. HTTP and UDP proxies had the same pattern.
Bind the Close method value before reassignment, and add an e2e test
verifying that the local connection is closed after the user
disconnects.
* test/e2e: replace sleeps with event-driven waits in chaos/group/store tests
Replace 21 time.Sleep calls with deterministic waiting using
WaitForOutput, WaitForTCPReady, and a new WaitForTCPUnreachable helper.
Add CountOutput method for snapshot-based incremental log matching.
* test/e2e: validate interval and cap dial/sleep to remaining deadline in WaitForTCPUnreachable
Replace the fixed 500ms sleep after each frps startup in RunProcesses
with a TCP dial-based readiness check that polls the server bind port.
This reduces the e2e suite wall time from ~97s to ~43s.
Also simplify the RunProcesses API to accept a single server template
string instead of a slice, matching how every call site uses it.