I'm new to Erlang, but I was wondering if it's possible to somehow attach to a working application and examine a ETS or DETS it's using. If yes, would you care to give a small example?
Thank you!
On
You can use Observer to view ETS tables if you have access to it. From erlang shell just type observer:start(). to open the GUI.
To connect to a running named node you use the connect to remote node option in Erlang Shell.
Start a named node
$erl -name application@hostname
From a different machine or terminal start a new erlang shell
$erl -name temp@hostname
From your temporary erlang shell connect to application by pressing Ctrl+g, followed by h or ? to get a list of options. Option r is connect to remote node and c to connect to new job.
>r 'application@hostname'
>c
After that you can call any commands as if you where on that machine, call any module:functions, and access the ETS tables.
If you are on the same machine there is nothing else, if you are on different machines you must set the cookies so that they match, otherwise you will not be able to connect.
Be careful when disconnecting, you must switch to your local node before quitting, or killing the temp application, don't kill the real application.
Rebar3
Many people use Rebar3 for creating and running Erlang projects these days, if you don't I strongly recommend using it.
With Rebar3 you start an application using the start command and use the attach command to attach to a running application. You must make a release with Rebar3 to use these commands. More info here.
sample:
rel/my_app/bin/my_app start
rel/my_app/bin/my_app attach
after that do as mentioned above to get access to ETS or use any ets command listed in erlang man pages.
Use ctrl+D to detach.
Mix and Match
You can connect to a project started with rebar3 using the regular erl -name temp@hostname shell. As long as cookies match and you know the node name you don't have to use Rebar3 to attach to the running application.
There are two ways of doing that, both of which may or may not work depending on how the Erlang node was started:
to_erlerl -remsh) over Erlang distributionEither way, you end up with an Erlang shell where you can inspect your tables.
run_erl and to_erl
If the Erlang node was started with the
run_erlwrapper, then you can connect to the running node withto_erl. You can see therun_erlcommand used by running:For example, if the Erlang node was started with this command:
then the three paths in the command correspond to:
You want the first one for
to_erl, so the command would be:Note the trailing slash!
to_erlgets confused if it is missing.To exit, type
Ctrl-D.Connect using Erlang distribution
If the Erlang node is running as a distributed node, and you know the secret "cookie", you can start another node and open a remote shell.
Which node name? Long or short?
You need to know the node name of the running node, and also whether it's running with "long" or "short" node names.
In a "long" node name, the host part is a fully qualified domain name or an IP address, but in a "short" node name, the host part is just a host name, without dots. If the Erlang node was started with the
-nameoption, it's using long node names, and if it was started with the-snameoption, it's using short node names. If neither option was used, it's not a distributed node and it's not possible to connect to it.1And the host name might be explicit or implicit in the command. If the command looks like one of these, you already know the exact node name:
But if the
-nameor-snameoption only specifies the "bare" node name, you'll need to figure out what host name it chose to start with:What is the cookie?
When one Erlang node connects to another, both nodes need to have the same "cookie" configured, otherwise the handshake will fail. The cookie can either be read from the file
.erlang.cookiein the home directory of the user that the Erlang node is running as, or set explicitly with the-setcookiecommand when starting the node.Let's connect!
So now we know:
-nameor-sname(i.e. long or short node name)-setcookieNow we can connect! We need to start a temporary Erlang node that:
-nameor-sname, according to what the running node was started with-setcookieoption as the running node, or runs as the same user to access the same.erlang.cookiefile-remsh("remote shell") to connect to the running node.-hiddento avoid being seen as part of the Erlang clusterSo something like this:
This should open a shell on the running node. You can tell by looking at the prompt, which should tell you the node name:
If it doesn't show the right node name, see the question Erlang remote shell not working.
To exit, type
Ctrl-gand thenq.Examine ETS or DETS tables
Once you have an Erlang shell, you can inspect the tables. Use
ets:all()ordets:all()to list the existing tables. For ETS, you can then useets:tab2list, which shows all entries in a table:For DETS, you can use
dets:match_objectwith the'_'wildcard pattern:1 Except if the node was started as a non-distributed node and later turned into a distributed node with
net_kernel:start.