I would like to demonstrate the use of the :observer GUI from a remote IEx shell. My target is BEAM running my Elixir app on a resource contrained embedded system.
I built the remote OS using Buildroot including support for Erlang. I added a checkout of the elixir-lang repo to give me Elixir and IEx. (Version is reported as 1.13.0-dev and I'm using Erlang/OTP 22.)
My host OS is Ubuntu and I'm using the same versions of Elixir and OTP for consistency.
I start my app on the remote machine with:
iex --sname foo --cookie <cookie> -S mix run
and connect to it from my host with:
iex --sname bar --cookie <cookie> --remsh foo@<remote machine name>
This gives me a remote shell. However when I try entering :observer.start()
, I get an error, ERROR: Could not find 'wxe_driver.so' in: /usr/lib/erlang/lib/wx-1.9/priv
The .so file actually exists at that path on my Ubuntu machine, but not on my embedded system which lacks WX widgets (and X windows and any sort of graphical output hardware). Is there any way around this? Have I done something wrong?
The problem is with --remsh
. Using --remsh
will open a remote session like you were executing IEx from that machine in a similar way of a typical SSH session.
You need to connect to the remote node from a local IEx session using Node.connect/1
and then open the Observer :observer.start()
. This will require SSH access to the remote machine (your embedded system) and the forward of two ports from that system to your localhost.
The first port is from epmd
- the Erlang Port Manager Daemon - and the second port is from your system's node.
epmd -names
on your embedded system to get both ports.After that make sure epmd
is not running on your localhost (ps aux | grep epmd
and kill it if it's running). It should be running only on your embedded system.
Forward both ports to your localhost:
$ ssh user@remote-embedded -L4369:localhost:4369 -L41437:localhost:41437
Again on localhost start a new IEx session (without --remsh
):
$ iex -name bar@127.0.0.1 --cookie mycookie
Connect to the remote system from this IEx session:
> Node.connect(:"foo@127.0.0.1")
This should return true
. Note that I'm using long names (the -name
and not -sname
like you did), but short names should also work.
Finally open the Observer:
> :observer.start()
Select your remote system from the "Nodes" menu.
This works because Observer runs a several of RPC calls to the remote machine in order to get data from that system. This way you don't need anything "graphical" installed on your embedded system.
To know more, see http://blog.plataformatec.com.br/2016/05/tracing-and-observing-your-remote-node/