Breaking changes
Observability
EventTraceContextAPI change: theEventTraceContextstruct forferron_observabilityhas been updated to includetracestate. If your custom Ferron modules rely on theEventTraceContextstruct, you may need to update it to includetracestate(you can usetracestate: None).
Added
Runtime
- Support for pinning into specific CPU cores: Ferron now supports pinning worker threads to specific CPU cores (for asymmetric CPU cores and NUMA). This can be configured via the
cpu_affinitydirective in the global configuration block.
Changed
HTTP server core
- HTTP body buffering: added support for disabling request and response body buffering using
Incremental: ?1orX-Accel-Buffering: noheaders.
Observability
http.routeis now a route template: previously, theferron.requestspan reportedhttp.routeas the requested hostname (or"*"). It now reports the matched route template built from the configuredlocationblock names, for example/api/users/:id, and is omitted when nolocationblock matched.ferron.hostadded to request spans: the requested virtual host is now reported asferron.hoston theferron.requestspan. It uses the same attribute name as the TLS metrics, so traces and metrics join on the same key.server.addressis unchanged and still reports the bound socket address.- Sampling probability reported in
tracestate: when Ferron starts a trace itself andtrace_samplinguses a ratio, the request's trace context now carries the OpenTelemetryottracestateentry (for exampleot=0.1), on the propagated headers and on the exported span. Backends that extrapolate sampled traces can scale counts back up; previously a ratio sampler silently reported only the sampled fraction of traffic. Nootentry is written foralways_on,always_off,parentbased_always_on, a ratio of1.0or0.0, orattribute_basedsampling. An incomingtracestateis passed through unchanged. - Active health checking metric attributes: the metrics related to active health checking now have resolved IP address attributes when
metrics_resolved_ipis enabled (similarly to circuit breaker metrics). - Aggregate active health checking partial success metrics: added a
ferron.proxy.health.partial_successmetric that reports health check probe results that succeeded only for some backend servers (percentage of successes in 0.0-1.0 scale). - Circuit breaker and active health check status metrics for multi-address upstreams: improved overall metric clarity and reduced ambiguity when
metrics_resolved_ipis disabled. - TLS and HTTP protocol error log improvement: when server is logging to text-format application logs (not JSON structured ones), it now logs client IP address and port for TLS and HTTP protocol error logs.
HTTP server core
request.uri.pathimprovement: therequest.uri.pathvariable is now resolving to URL-decoded value for more consistent matching.request.uriandrequest.uri.queryare documented as not necessarily URL-decoded.
Fixed
HTTP server core
trace.idandspan.idresolution fix: previously,trace.idandspan.idvariable interpolations resolve to a doubly hex-encoded IDs, not proper single hex-encoded values.HEADrequest response body discard: When sending a response for an HTTPHEADrequest, the response body is now discarded instead of being sent to the client, improving HTTP spec compliance (seezincio-httpchangelog).- Conditional configuration validation: the server is now reporting (via
ferron validate) invalid forms ofif,if_not,locationandhandle_errordirectives. - HTTP/3 protocol hardening: hardened the HTTP/3 implementation against potential QPACK decoding vulnerabilities (see
zincio-httpchangelog).
Observability
tracestateis now exported on spans: the OTLP exporter wrote an emptytrace_stateon every span, discarding the W3Ctracestatethat Ferron parses and propagates to upstreams. The span now reports it.- Span trace flags follow the sampling decision: the OTLP exporter hardcoded the "sampled" flag on every span. The flag sent to the OTLP backend or collector now reflects the recorded decision.
- Prometheus scrape error metric: previously,
ferron_prometheus_scrape_errors_totalmetric didn't increase at all. This has been fix to increase when an internal error with Prometheus endpoint occured. - Connection pool metric fix: previously, outstanding connection count measured from exported metrics (like Prometheus or OTLP) was bogus, it didn't decrease properly due to a logic bug.
Reverse proxying
- Strict-DNS URL resolution fix: previously, strict-DNS URL resolution dropped the upstream path prefix (like
/apiinhttp://backend.example/api). This has been fixed to preserve the upstream path prefix.