Release v1.59.0
🚀 Features
🔹 Push-based OTLP Metrics Export
Metrics can now be pushed over OTLP alongside the existing Prometheus pull endpoint, for
serverless and ephemeral deployments — Cloud Run scale-to-zero, short-lived jobs — where a
scrape interval simply misses the process. An OTel MeterProvider supports several readers on
the same instruments, so the Prometheus reader and the OTLP push reader run together with no
double-counting.
The two concerns are independent switches, and the default is unchanged: with no new config
set, metrics stay Prometheus pull-only, byte for byte as before.
| Concern | Control | Default |
|---|---|---|
Prometheus pull /metrics
| METRICS_PORT (0 disables)
| on (2121) |
| OTLP push | METRICS_EXPORTER=otlp
| off |
METRICS_EXPORTER=otlp
OTEL_EXPORTER_OTLP_ENDPOINT=https://collector:4318Resolves discussion #3366. — #3761
🐛 Fixes
🔹 S3 file store: io.Copy no longer hangs and OOM-kills the process
Read returned len(p) with a nil error regardless of how many bytes were actually read, so
io.Copy(w, s3file) never saw EOF and reallocated a growing buffer on every iteration. That path
is now correct and linear. Also in the same fix: Create works on a fresh prefix, and object
metadata is treated as optional. Fixes #3804. — #3805
🔹 Static endpoints serve their index page instead of 403 or an endless redirect
A request for the root of a static endpoint never served that directory's index — two separate
regressions, from #2759 and a later change, surfacing as a 403 or a redirect loop.
examples/using-html-template answers GET / correctly again. Fixes #3819. — #3820
🔹 Data race on server shutdown, plus de-flaked cron and file-token unit tests. — #3800
🔐 Security
🔹 /.well-known/health no longer leaks backend inventory to unauthenticated callers
The health endpoint is served unauthenticated, but returned the full Container.Health() map:
datastore hosts and ports, database / keyspace / bucket names, connection-pool statistics, the
Elasticsearch username, and raw error strings. Anyone able to reach the app port could enumerate
the backend inventory with no credentials.
The public endpoint is now redacted to {name, status}. Container.Health() keeps the full map
for in-process operational use, and no exported API changed. Fixes #3802. — #3807
🔹 grpc bumped to v1.83.0 in examples/using-s3-filestore, resolving
GHSA-hrxh-6v49-42gf. — #3920
⚡ Performance
🔹 Fewer allocations on the request hot path
Four focused changes across logging and HTTP response, each guarded by a benchmark and an
equivalence test. No public-API, wire-shape, or environment-variable change.
| benchmark | time | B/op | allocs/op |
|---|---|---|---|
ResponderRespond
| 380 → 334 ns (−12%) | 249 → 72 (−71%) | 4 → 2 |
getIPAddress
| 59 → 26 ns (−56%) | 48 → 0 (−100%) | 1 → 0 |
ContextLogger.Info
| 584 → 461 ns (−21%) | 568 → 216 (−62%) | 9 → 6 |
Logger.Info (JSON)
| 513 → 393 ns (−23%) | — | — |
Roughly −577 B and −6 allocations on a typical request. — #3758
Full changelog: v1.58.0...v1.59.0