kerryb

kerryb

Telemetry/PromEx metrics in a cluster

Sorry if this is a daft question, but I can’t seem to find any documentation that answers my question …

We’re in the process of migrating a Phoenix application from a single node to an OTP cluster. Almost everything is working nicely, apart from some custom metrics we’re using to track usage of various parts of the application.

We have a simple prom_ex plugin added to our prom_ex plug, which handles telemetry events that we send when certain actions happen,. Here’s a slightly simplified version:

defmodule MyApp.PromEx.StatsMetrics do
  use PromEx.Plugin

  @impl true
  def event_metrics(_opts) do
    Event.build(
      :my_app_stats_event_metrics,
      [
        sum(
          [:my_app, :stats, :page_visits],
          tags: [:tool, :role],
          description: "The count of a tool being visited by someone in a role"
        )
      ]
    )
  end
end

… with events are emitted at appropriate points:

:telemetry.execute([:my_app, :stats], %{page_visits: 1}, %{
  tool: :some_tool,
  role: user.role.name
})

The problem is that we now have one instance of the plugin running on each node in the cluster, so stats are recorded separately for each node, and when Prometheus scrapes the numbers it sees the counts varying wildly as the load balancer routes it to a random node each time.

What we’d like to end up with is either a single instance of prom_ex (or just this plugin?) on the cluster (eg using highlander), or to somehow guarantee that the events are broadcast (using Phoenix pubsub, maybe?) so that all instances of prom_ex show the same values (but then what happens when a node is temporarily taken out of the cluster for an application upgrade?)

It feels like there’s probably a simple way of achieving this and I’m missing something obvious – any ideas?

Thanks!

Most Liked

hauleth

hauleth

We exposé metrics for individual clients as well, so we would need that gathering metrics from all nodes anyway. That way it is also easier to gather metrics as we support self-hosting, which makes the operations much easier. And with current implementation it is quite robust solution.

hauleth

hauleth

That is bad idea. What if the node storing all metrics will go down? You will lose everything you have.


In Supavisor we had encountered similar problem and our solution was pretty different:

  • each node collects their own metrics
  • at the time of export we traverse metrics from all nodes and merge them
  • then we do export

Code:

https://github.com/supabase/supavisor/blob/c38a7bd98528185ad4142666094873ba4f5e2d50/lib/supavisor/monitoring/prom_ex.ex#L126

This requires Peep as a storage backend (which is much more performant from my experience).

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement