bglusman

bglusman

So, I’m loving LiveDashboard and learned a bit about telemetry, but still fairly new to LiveView for what it’s worth. The most frustrating part of the LiveDashboard experience for me is that, whether for demoing or using the dashboard for actual debugging, when you first open it up, there’s no data. Now, I know it’s out of scope for LiveDashboard to handle storing historical info from telemetry, and I have the storage of it solved easily using a ring buffer in a genserver that I already need running anyway for telemetry_poller to aggregate metrics within a tick on my customized metrics, but there are no hooks into LiveDashboard for populating a new client with a limited amount of history so that new clients can always have a little bit of history right away without waiting.

I opened this issue looking for maintainer input on the best way to structure the hook, after José indicated he was open to accepting a hook as a PR, but it’s not a priority for them right now so I’m looking for input here, both about interest level and if anyone has a good instinct from LiveView in general or LiveDashboard/Phoenix internals in particular on the best/most conventional structure and placement for such a hook. I started some work in a fork linked in the issue, but a) it’s not quite working correctly, and b) I suspect it might be preferred to have the client emit a new event (or use an existing client connection event) as the trigger, whereas right now I’m using a :telemetry.execute event as the trigger, and probably need the actual hook to be different/more conventional and similar to how the ordinary telemetry updates get dispatched to the client, but I think not as telemetry as I think each payload needs the be specifically crafted to be the history just for that client based on its moment of connection, as it will receive all future updates through ordinary means.

Look forward to hearing some feedback!

Showing Posts 1 to 10

LostKobrakai

LostKobrakai

Generally I’d not use telemetry for retrieving historical data at all. There could be a config like:

config :live_dashboard, MyLiveDashboard,
  historical_data: %{
    [:my_app, :repo, :query] => {MyStorage, :historical_metric_data, []}
  }

Which would make the dashboard run MyStorage.historical_metric_data([:my_app, :repo, :query]) when it comes to rendering a chart for [:my_app, :repo, :query].

bglusman

bglusman OP

I like that API! And yeah, the idea wasn’t to use telemetry for retrieving it, but only as the trigger for a hook, but I think I like your idea better since it should involve no overhead when there’s no config present, whereas mine involved a receive call and a short timeout… I’ll start playing with that next, thanks @LostKobrakai and welcome any other thoughts of course also.

Presumably in above example if the argument list were non-empty, then historical_metric_data would have arity > 1 ? I suppose having an additional argument that could be a function passed in or something could make sense. Thanks again!

LostKobrakai

LostKobrakai

I’d basically prepend the event name to the args of the config, so the actual function would need an arity of +1 to the length of arguments in the config.

bglusman

bglusman OP

Oh so you think instead of MyStorage.historical_metric_data([:my_app, :repo, :query]) it would call MyStorage.historical_metric_data(:my_app, :repo, :query) and +1 to arity for each additional argument in the config list? Yeah not sure but that makes sense/is how I first read your code before I noticed it as a list… I remember seeing a convention like this in some other library recently but blanking what it was maybe something in ecto or telemetry_poller, I forget

LostKobrakai

LostKobrakai

Nope, I meant it like your first example: prepend the full event name as the first argument.

bglusman

bglusman OP

:+1: apologies, that’s what I’d tried to convey in my first reply which made me think you were correcting a misunderstanding there.

I also wonder though, your example above looks to use Application config, but it looks like the only config live_dashboard currently takes is in the arguments in router to live_dashboard, so guessing we’d pass in historical_data as an additional optional config there, e.g.:

  scope "/live-dashboard" do
    pipe_through [:browser, :admin]
    live_dashboard "/",
      metrics: MyApp.Telemetry, 
      historical_data: %{
        [:my_app, :repo, :query] => {MyStorage, :historical_metric_data, []}
      }
  end
LostKobrakai

LostKobrakai

That would probably work as well. Skipping the app env when possible is usually a good thing.

bglusman

bglusman OP

Hopefully also can treat the keylist as a prefix rather than an explicit match so for large numbers of metrics you can just put in the namespace they’re in once, e.g. [:my_app, :repo] and get all events that start with that… probably what you intended but just stating here as I’m toying with starting this in case anyone disagrees.

bglusman

bglusman OP

For anyone interested, a quick v1 of above is pushed up here GitHub - bglusman/phoenix_live_dashboard at historical_data · GitHub and I think this may work but had to break before I could start real testing, code reviews or testing suggestions welcome!

bglusman

bglusman OP

OK, pushed up a few more changes, this is working on the backend but there’s two different initialData functions in assets/js/metrics_live/index.js and I think all that’s needed is for one or both of them to be wired up to check for the hidden history div I added and parse in any spans there the same way it brings in data on liveView updates… if by any chance @LostKobrakai since it looks like you did most of the switch over from charts.js to uPlot you know the easiest/cleanest way to do that, I think that may finish this off, and I’d love your input on the implementation besides that, awesome, if you don’t have time, thanks for your help earlier anyway as it feels close now!

Where Next? Top

Trending in Discussions Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
achempion
I’ve been using Emacs as my main code editor for more than a two years. It’s a custom build version although I’ve tried doom emacs and sp...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New
jtormey
Lately I’ve been thinking about how to organize components as a LiveView application grows. One of the pain points I’ve found (for myself...
New
Null-logic-0
What IDE or editor are you using for Elixir development? Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews