Is there something like `ps aux` or `top` for Erlang?

Looking for something that:

  1. lists all running Erlang processes

  2. lets me kill them (even if they are infinite looping)

Yes, and you can either use a library for that like recon (recommended) or write functions that do that yourself.

Naively it can be done like this:

# gets reductions count for each process in the system
# afaik what reductions are exactly is not documented to avoid people doing premature optimisations
# but they can be thought of as a proxy for cpu load where more reductions means more load
iex> before_sleep = Map.new(Process.list(), fn pid -> {pid, pid  |> Process.info(:reductions) |> elem(1)} end)
# %{#PID<0.481.0> => 17147, ...}

# to get more accurate measurements, we need to make at least two probes spaced out in time
iex> :timer.sleep(1000) # sleeps for one second
:ok

iex> after_sleep = Map.new(Process.list(), fn pid -> {pid, pid  |> Process.info(:reductions) |> elem(1)} end)
# %{#PID<0.481.0> => 17147, ...}

# finds processes that had the most reductions within the last second
iex> top3 = after_sleep |>
...> Enum.map(fn {pid, reductions} -> {pid, reductions - before_sleep[pid] || 0} end) |> 
...> Enum.sort_by(fn {_pid, reductions} -> reductions end, :desc) |>
...> Enum.take(3)
[
  {#PID<0.527.0>, 99167},
  {#PID<0.63.0>, 6580},
  {#PID<0.65.0>, 3139}
]

# note that in my case <0.527.0> is the shell process so killing it restarts the shell
iex> Process.exit(pid(0, 527, 0), :kill)
** (EXIT from #PID<0.527.0>) shell process exited with reason: killed

Interactive Elixir (1.12.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

Useful links:

4 Likes

There is also this video.

at around 23 minutes… there is something similar done in the demo.

2 Likes

:observer.start as well.

2 Likes