Observer is a graphical tool for observing Erlang systems. It works just fine for inspecting Elixir systems. It displays system information, application supervision trees, process information, ets and mnesia tables, and provides a means to do tracing via a graphical frontend.

I had a terrible time getting Erlang to support wxWidgets, but ultimately found out it was because I had wxWidgets 3.1 installed, and Erlang really just doesn't build against that version properly. I downgraded to 2.8 and it worked immediately.

At any rate, let's dig in.

Project

We're going to use Observer to observe what's happening in BEAM Toolbox while it's running. We'll kick off the BEAM Toolbox:

iex -S mix

Alright, so we can visit the homepage in the browser:

(visit http://localhost:4000/pages/home)

Now from the iex session, fire up observer with:

:observer.start

OK, so now we're presented with a big graphical window. It has a few tabs at the top: System, Load Charts, Applications, Processes, Table Viewer, and Trace Overview.

We can use these tabs to dig into various pieces of the running system. Under the System tab, you can see various bits of information about our system:

  • total memory usage, along with where it's spent
  • Erlang and erts versions, as well as the architecture
  • CPU and scheduler information
  • System uptime, number of processes in the system, etc.

Next, we'll have a look at the load charts. Here you can see how the system's operating and how much memory it's used over time, etc.

Next, you can look at the running applications. You can see we've got apps running for mic, phoenix, beam_toolbox, and elixir, as well as lots of other small applications that have been loaded in support of our application or its dependencies.

If we click on beam_toolbox, then we can see its supervision tree. At the bottom of it, you can see the process for the cadfaerl cache for github. Let's open that up.

Alright, in a given process you can see a lot of information. Here, we can his group leader, as well as how many reductions he's run through. You could look at the messages in his mailbox, if he had any. You can see the process dictionary, which we've not really gone into much yet. You can see his stack trace, which shows you the MFA as well as the file and line number he's currently running. Finally, you can see the process's state. So cadfaerl is a cache implemented as a gen server, if you'll recall. His state can be expanded by just drilling into it (click here to expand above term).

Alright, so here you can see what his current state is. It's just an empty dict, because he doesn't have anything in his cache yet. Let's change that - we'll go click on the Amrita project, and it will look in the cache for data for the various pieces it cares about, come up empty, and then proceed to request data from the github api and fill the cache with that data when it gets it back.

Now let's go back to the process's state in Observer, and refresh our view:

(refresh)

Now you can see the data the process is holding onto for us.

Let's go back to the Load Charts tab and have a look at them - you can see our memory consumption jumped up a bit. Let's visit another project and watch the memory go up a bit more as it has to cache the data from that project as well:

(do it)

Alright, so it's actually going to be a very minimal amount of new memory consumed, so it may not be terribly visible depending on the scale of the graph.

I think this is a fantastic bit of tooling, and something I've often wished to have in systems I've built in Ruby. This is just another one of the great tools the Erlang ecosystem provides to developers.

Summary

We didn't even get too in depth with Observer - there's still a way to view ets tables, a graphical trace tool that we'll probably play with more in the future, and a process list you can use to view any processes, not just those in an application's supervision tree. I think you'll have fun exploring it further. See you soon!

Resources