Spans model per-action operations (open/message/close); they're a poor fit for ad-hoc
events with no operation lifecycle. Split logError to dispatch by whether a span is
active:
- Active span (realtime.open / realtime.message / realtime.close catches) -> attach
the error to the existing span; the Sentry span exporter ships it with full operation
context (attributes, duration, trace_id).
- No active span (pub/sub subscriber, onStart, Swoole error handler, updateWorkerDocument)
-> push a utopia/logger Log via the realtimeLogger registry. Goes to Sentry as an event
via the Sentry logger adapter (or to logOwl / Raygun / AppSignal). Same dedicated
Realtime project either way.
Restores the realtimeLogger registry (dropped in the previous "spans only" pass), inlines
the now-single-caller $createLogger closure into the logger registry, and drops the
recordRealtimeErrorSpan helper — logError is the only function on this path now.
Also registers a Pretty span exporter in app/init/realtime/span.php for non-self-hosted
editions so Realtime spans are visible in the container's stdout (on self-hosted the
existing app/init/span.php already provides it; gating avoids duplicate output).
Collapse the multi-line doc blocks on recordRealtimeErrorSpan / pushRealtimeErrorLog /
$createLogger to one line each, drop the redundant require comment, and tighten the
"keep in sync" notes — keeping the cross-references and the double-report hazard.
The realtimeLogger registry was a ~40-line copy of logger; extract the
DSN -> adapter -> Logger construction into one $createLogger closure used by
both. realtimeLogger now just resolves _APP_LOGGING_CONFIG_REALTIME (falling
back to _APP_LOGGING_CONFIG), skips Sentry — those errors go out as spans via
app/init/realtime/span.php — and delegates the rest. Cross-referenced the two
"sentry" conditions in both files. No behavior change (legacy ;-delimited
config no longer crashes the realtime registry; it disables logging like the
main one).
Move the Realtime Sentry span exporter registration out of app/realtime.php
into app/init/realtime/span.php (mirrors app/init/span.php / app/init/realtime/
connection.php), and split the now-80-line logError() into recordRealtimeErrorSpan()
(span path) and pushRealtimeErrorLog() (legacy utopia/logger path, non-Sentry
providers only), leaving logError() a small orchestrator. No behavior change.