{"id":5387,"date":"2016-05-10T19:41:48","date_gmt":"2016-05-10T22:41:48","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=5387"},"modified":"2016-10-31T16:57:16","modified_gmt":"2016-10-31T18:57:16","slug":"tracing-and-observing-your-remote-node","status":"publish","type":"post","link":"http:\/\/blog.plataformatec.com.br\/2016\/05\/tracing-and-observing-your-remote-node\/","title":{"rendered":"Tracing and observing your remote node"},"content":{"rendered":"

Today we will continue exploring techniques for debugging and tracing Elixir code that are so important for running and understanding production systems.<\/p>\n

In the past, we have discussed:<\/p>\n

    \n
  1. how to debug your application<\/a><\/li>\n
  2. how to trace systems with Erlyberly<\/a><\/li>\n
  3. how to use the observer to introspect applications<\/a>.<\/li>\n<\/ol>\n

    The examples above always connected to systems running locally. Given Elixir’s and the Erlang VM focus on distributed systems, you may have wondered: can we use the VM capabilities to trace and observe remote nodes?<\/p>\n

    Certainly!<\/p>\n

    Your application runs as part of the Erlang Runtime System, which is often called a node, as it may connect to other machines. Before we establish such connections, let’s get to know some concepts and then configure our applications.<\/p>\n

    EPMD<\/h2>\n

    Erlang Port Mapper Daemon<\/strong>, EPMD, acts as a name server on all hosts involved in distributed Erlang communications. When an Erlang node starts, the node has a name and it obtains an address from the host OS kernel. The default port the daemon runs on is 4369 but you can change it with the ERL_EPMD_PORT<\/code> environment variable <\/a>.<\/p>\n

    You can run epmd -names<\/code> to check the port and the nodes connected:<\/p>\n

    user@localhost:~$ epmd -names\nepmd: up and running on port 4369 with data:\nname myapp at port 43316\n<\/code><\/pre>\n

    SSH Port Forwarding<\/h2>\n

    Depending on your firewall configuration, the port 4369 from EPMD is blocked by default. We will use port forwarding to redirect our local EPMD port to the remote EPMD with ssh<\/code>: ssh user@myapp.com -L4369:localhost:4369<\/code>.<\/p>\n

    Therefore, when we start a node locally, it will attempt to register itself to the EPMD running on port 4369, which is effectively forwarded to the remote EPMD. Once our local node registers itself to the remote EPMD, it will be able to find all remote nodes running on the remote EPMD.<\/p>\n

    Configuring the Phoenix application<\/h2>\n

    Imagine we want to trace or observe a Phoenix project. In our case, our project was released using exrm<\/a> and our release path in production has a directory called running-config<\/code>. In this directory we can find the files sys.config<\/code> and vm.args<\/code>.<\/p>\n

    The file vm.args<\/code> is responsible for configuring our application when it starts. Let’s change it as follows:<\/p>\n

    ## Name of the node\n-name myapp@127.0.0.1\n-kernel inet_dist_listen_min 9001 inet_dist_listen_max 9001\n\n## Cookie for distributed erlang (you want a really long cookie)\n-setcookie my_cookie\n<\/code><\/pre>\n

    We added a name to your application, set a port range where remote nodes may connect to and chose a cookie secret. If your server was already running, you will need to restart it after changing vm.args<\/code>.<\/p>\n

    After restarting our application, we should see it registered in the remote EPMD:<\/p>\n

    user@localhost:~$ epmd -names\nepmd: up and running on port 4369 with data:\nname myapp at port 9001\n<\/code><\/pre>\n

    Tracing application<\/h2>\n

    After our application is started, we need to change our ssh<\/code> command to forward to EPMD and our application ports: ssh user@myapp.com -L4369:localhost:4369 -L9001:localhost:9001<\/code>.<\/p>\n

    Now let’s start the tracing tool locally with the proper cookie options. The tracing tool will register itself to the remote EPMD, via port forwarding, and find our remote application. Once the Erlyberly is started, you should see the following in the remote EPMD:<\/p>\n

    user@localhost:~$ epmd -names\nepmd: up and running on port 4369 with data:\nname myapp at port 9001\nname erlyberly-1460466831146 at port 54420\n<\/code><\/pre>\n

    Observing application<\/h2>\n

    We can also observe a remote system using ssh port forwarding. One option is to establish a remote shell, as explained in the IEx documentation<\/a>:<\/p>\n

    $ iex --name mylocalmachine@127.0.0.1 --cookie my_cookie --remsh myapp@127.0.0.1\n<\/code><\/pre>\n

    Now you are connected directly to a remote node and you can introspect it as well as start tools like Observer.<\/p>\n

    Alternatively, you can start a new local shell with the same cookie as the remote node:<\/p>\n

    $ iex --name mylocalmachine@127.0.0.1 --cookie my_cookie\nErlang\/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]\n\nInteractive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help)\niex(mylocalmachine@127.0.0.1)1> :observer.start()\n:ok\n<\/code><\/pre>\n

    The local shell should be registered in the remote EPMD alongside the remote system:<\/p>\n

    user@localhost:~$ epmd -names\nepmd: up and running on port 4369 with data:\nname mylocalmachine at port 50055\nname myapp at port 9001\n<\/code><\/pre>\n

    With Observer open, we can now change the inspected node using the menu ‘Nodes > Connect node’. In the prompt we can fill in the node name. In our example the node is myapp@127.0.0.1<\/code>.<\/p>\n

    \"Observer\"<\/p>\n

    Troubleshooting<\/h3>\n

    You may receive an error similar to the one below when you try to connect through Observer:<\/p>\n

    16:38:44.278 [error] [node: :\"mylocalmachine@127.0.0.1\", call: {:observer_backend, :sys_info, []}, reason: {:badrpc, {:EXIT, {:undef, [{:observer_backend, :sys_info, [], []}, {:rpc, :\"-handle_call_call\/6-fun-0-\", 5, [file: 'rpc.erl', line: 206]}]}}}]\n<\/code><\/pre>\n

    This occurs because the :observer_backend<\/code> is disabled. You can enable it by adding the :runtime_tools<\/code> to your application mix.exs<\/code> file. You can get more details in the Runtime tools documentation<\/a>.<\/p>\n

    Do you use other techniques to connect to remote nodes? Share your tips with a comment below.<\/p>\n


    \n


    \n\"What's
    \n<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

    Today we will continue exploring techniques for debugging and tracing Elixir code that are so important for running and understanding production systems. In the past, we have discussed: how to debug your application how to trace systems with Erlyberly how to use the observer to introspect applications. The examples above always connected to systems running … \u00bb<\/a><\/p>\n","protected":false},"author":18,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[247,143,245],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5387"}],"collection":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=5387"}],"version-history":[{"count":8,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5387\/revisions"}],"predecessor-version":[{"id":5396,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5387\/revisions\/5396"}],"wp:attachment":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=5387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=5387"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=5387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}