Repository navigation
feat(diag): browser-based diagnostics viewer over OSC - #1807
dedicatedbroadcastsolutions wants to merge 10 commits into
Conversation
Prototype replacement path for the SFML DIAG window (see issue CasparCG#899), built to be lightweight and usable both as a standalone browser page and as a feed other clients can subscribe to and render/process themselves: - core/diagnostics/web_graph: a graph_sink that mirrors every graph's text/values/colors/tags into an in-memory snapshot. Registered alongside (not instead of) the existing osd sink, so it costs nothing beyond what set_value() already costs regardless of DIAG - no rendering happens here at all. - protocol/util/diag_http_server: a minimal GET-only HTTP/1.1 responder over raw asio (no boost::beast, no new dependency): GET / -> static HTML/JS viewer, all rendering is client-side canvas, connects to /events GET /snapshot -> one JSON snapshot, for simple polling clients GET /events -> Server-Sent Events stream of JSON snapshots, for clients that want to subscribe and do their own rendering/processing - Disabled by default; opt in via configuration.diag.http-port in casparcg.config. No auth - trusted monitoring network only, same as OSC/AMCP. core and protocol build clean. Full executable build (all modules) still in progress in a slow single-core environment as of this commit; will confirm server.cpp integration compiles once that finishes.
Rename configuration.diag.http-port to configuration.diag.default-port and default it to 4000 (instead of 0/disabled), matching how OSC's client is always active by default (configuration.osc.default-port). 0 still disables it for anyone who wants it off.
… severity Match osd_graph feature-for-feature so the web viewer is a complete replacement: - capture call_context (channel/layer) at sink creation and show it per graph, like the corner label in the SFML window - assign each sink a stable id instead of keying the client-side viewer by registry position, so graphs cannot get relabeled or merged as others are created/destroyed - remove a graph from the page once its id stops appearing in a snapshot, matching the SFML window dropping a destroyed graph's weak_ptr - store set_tag() severity per named series (as osd_graph does) instead of a flat, never-cleared list of tag names, clearing pending tags once emitted so the web page only shows tags that fired since the previous snapshot, and render them as small severity-colored badges - fix auto_reset() to decay values back to 0, matching osd_graph, rather than clearing tags
…eries Default (unset) line color now matches osd_graph's white default instead of an arbitrary green, and explicit graph_->set_color() values already decoded with the same bit layout as get_sfml_color so they render identically. dropped-frame, late-frame, flushed-frame, underflow, drop-out, audio-clipping and audio-buffer-overflow are often configured with dark, muted tones in the SFML modules (meant to sit quietly alongside busier lines there). On the web viewer these are normalized to a vivid version of the same hue and drawn with a thicker, glowing stroke so problems are obvious at a glance.
Same C++20 modernization as CasparCG#1805 - drops the fixed-size stack buffer and <cstdio> include in favor of std::format.
|
As much as I love the idea of ditching the DIAG window, I don't think bolting a web server onto CasparCG Server is the right direction. I like the idea of spitting out diagnostics through OSC via an opt-in option. That way, people can use their preferred GUIs to show that data in their preferred way. And those who don't use it won't be bothered by it. I go by the motto "the best code is no code at all", so the more "features" we can strip out of the core Server code, the better. IMHO, of course. |
|
Ok, I can shift it towards that direction if we want to do it via OSC. Using a browser with SSE shifts the render off with minimal overhead of serving a basic web page. Since X11 is going away, I am not sure we can call diag replaced without having a UI for it shipped with the server, but I can make a simple UI that is a separate light weight web server executable that can provide that functionality for those who need it while keeping with your motto for the server core. |
Sending diag info over OSC would be great! |
|
I think that keeping this to OSC would be best. I had this in mind when doing 8f05ef7, my intention was that using that subscribe could accept an argument to say to include the detailed diag stuff too in some way (unsure how granular that should be) I can think of 3 different ways I would like to use this data, depending on setup/environment:
So ideally there could be a separate repo(s) in the casparcg github org for these tools. I dont have a particular preference on language for any of this, or whether its one repo with different tools or multiple repos. |
This comment has been minimized.
This comment has been minimized.
|
I have a typescript/electron front end that can be the web and desktop UI for this. I'll update this pr accordingly soon. |
Per PR feedback (dimitry-ishenko, Julusian), drop the bolted-on HTTP server and canvas viewer entirely in favor of broadcasting caspar::diagnostics::graph telemetry over the existing OSC transport, so people can use their preferred GUI/tooling instead of a server-shipped one: - core/diagnostics/web_graph -> osc_graph: the graph_sink mirror now builds a core::monitor::state snapshot (diag/<id>/channel, .../layer, .../text, .../value/<name>, .../color/<name>, .../tag/<name>) instead of a JSON string, so it can be sent down the same path as channel state. - protocol/osc/client: takes an optional diagnostics_provider callback and lets a subscription opt into diagnostics telemetry per-endpoint. Diagnostics are polled and broadcast on their own ~40ms cadence (they aren't tied to any channel's tick) but only while at least one endpoint has actually asked for them, so there's no cost at all otherwise. - protocol/amcp: `OSC SUBSCRIBE <port> DIAG` opts an AMCP client's existing OSC subscription into diagnostics; configuration.osc predefined-clients gained a matching <diagnostics> flag for static subscribers. - Removed protocol/util/diag_http_server and the configuration.diag section entirely - no more embedded web server/viewer in the core server. A separate TypeScript/Electron app (web + desktop) is where the actual viewer UI will live, consuming this OSC data directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
e47b29b to
ac9d531
Compare
|
Pushed an update that drops the embedded HTTP+SSE server/viewer entirely per the discussion above, in favor of broadcasting
Core, protocol, and the full executable all build cleanly with this change. The TypeScript/Electron app I mentioned will consume this OSC data directly and is where the actual viewer UI (web + desktop) will live, as a separate project outside this repo. |
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Prototype of a lightweight alternative to the SFML DIAG window: a small opt-in HTTP+SSE server that mirrors every
caspar::diagnostics::graph's text/values/colors/tags into JSON, with no rendering cost on the server.GET /- a small<canvas>-based viewer (all rendering client-side)GET /snapshot- one-shot JSON for simple polling clientsGET /events- Server-Sent Events stream for clients that want to subscribe and do their own rendering/processingconfiguration.diag.default-port(4000), matching how OSC's client is always active;0disables itCloses #899, #1310 (replaces the SFML DIAG window entirely, so it no longer competes for GPU/desktop resources). Related to #1361 (network-exposed graph stats — done over HTTP/SSE here rather than OSC), #1544 (per-port device labeling — not yet implemented, still channel/layer only), #1139 / #1654 (broader websocket control/monitoring proposals — this is a lighter-weight alternative for the monitoring half), #914 (motivation: avoiding desktop-GUI overhead on the server).
Status: draft. Core/protocol and the full executable build cleanly (confirmed both isolated and end-to-end), but I have not yet run this against a live playout server or exercised it under real load - want to validate the viewer/SSE behavior for real before marking ready for review.
Edit: This has been updated to be OSC instead of HTTP/SSE