Community
Mercure 0.24 adds native OpenTelemetry tracing for the Hub's core operations, lets you point at a JWK Set on disk instead of running a separate HTTP endpoint, and ships a Helm chart that satisfies the restricted Pod Security Standard out of the box. The tracing work is the headline: production hubs can now report accurate publish/subscribe latencies and topic cardinality to any OTel-compatible backend, with zero allocations when tracing isn't enabled.
✨ New Features
- Native OpenTelemetry tracing for the Hub's core operations:
mercure.publish,mercure.subscribe,mercure.subscriptions, andmercure.transport.history. Spans carry attributes likemercure.topics,mercure.update.id,mercure.private,mercure.subscriber.id, andmercure.last_event_id.requested. Spans nest under whatever parent span Caddy'stracingdirective produces, so the standardOTEL_*environment variables Just Work. When the directive isn't enabled,SpanFromContextreturns the noop tracer, with no allocations and no global state. Two new docs pages, Tracing and Metrics, document the spans and the Caddyfile setup by @dunglas in #1211 - Caddy:
publisher_jwks_urlandsubscriber_jwks_urlnow acceptfile://URLs in addition tohttp(s)://. Mount your JWK Set as a Kubernetes Secret/ConfigMap (or Docker volume) and point Mercure at it directly instead of running a sidecar HTTP endpoint. The file is read once at provision time; rotate keys with a Caddy config reload. HTTP/HTTPS URLs keep their background refresh behavior by @dunglas in #1239 - Helm: rootless restricted-PSS defaults. Container runs as UID/GID 1000,
drop: [ALL],allowPrivilegeEscalation: false,readOnlyRootFilesystem: true, plusfsGroup: 1000withfsGroupChangePolicy: OnRootMismatchso writable mounts (/data,/config,/tmp) stay writable for the non-root user without recursive chowns on every PVC remount. Completes the hardening trajectory from #1226, #1229, #1231, #1233, #1234. Binding to :80 relies onnet.ipv4.ip_unprivileged_port_start=0(containerd 1.5+, cri-o); older runtimes can switchservice.targetPortto8080by @dunglas in #1241
Enterprise
Mercure Enterprise's history-replay path is traced too: all four production transports (Redis, PostgreSQL, Kafka, Pulsar) start a mercure.transport.history span when dispatchHistory is called, with mercure.transport, mercure.subscriber.id, and mercure.last_event_id.requested attributes — matching the Community bolt transport. Errors on each transport's primary failure path (XRANGE, SELECT, consumer-group consume, Pulsar reader creation, message-ID decode) are recorded on the span via RecordError + SetStatus(Error, ...), so backends like Tempo, Jaeger, or Datadog surface them with full context.
Mercure Cloud tenants are already running on this release. Mercure Enterprise brings the same hardening and tracing on-premise plus the HA transports and priority support. Contact contact@mercure.rocks for the managed cloud offering, on-premise licenses, custom development, consulting, and training.
Full Changelog: v0.23.5...v0.24.0