Packages

A Mix task that helps you to observe your remote elixir nodes from your local machine.

Retired package: retired

Current section

Files

Jump to
remote_monitor lib mix remote_monitor.ex
Raw

lib/mix/remote_monitor.ex

defmodule Mix.Tasks.RemoteMonitor do
use Mix.Task
def run(args) do
[remote, app_cookie] = args
[user, host] = String.split(remote, "@")
:ssh.start
case SSHEx.connect(ip: to_charlist(host), user: to_charlist(user)) do
{:ok, conn} -> observe!(conn, "#{user}@#{host}", app_cookie)
{:error, reason} -> throw reason
end
end
def observe!(conn, remote_host, erlang_cookie) do
[app_port, epmd_port] = node_info(conn, erlang_cookie)
clean_up!(app_port, epmd_port)
start_tunnel!(remote_host, app_port, epmd_port)
start_observer!(erlang_cookie)
end
defp node_info(conn, erlang_cookie) do
result = SSHEx.cmd!(conn, 'epmd -names')
[[epmd_res]] = Regex.scan(~r/epmd: up and running on port [0-9]+ with data/, result)
[[epmd_port]] = Regex.scan(~r/[0-9]+/, epmd_res)
[[app_res]] = Regex.scan(~r/name #{erlang_cookie} at port [0-9]+/, result)
[[app_port]] = Regex.scan(~r/[0-9]+/, app_res)
[app_port, epmd_port]
end
defp clean_up!(app_port, epmd_port) do
Mix.shell.info("# Cleaning up old tunnels..")
Mix.shell.cmd("lsof -wni tcp:#{app_port} -t | xargs kill -9")
Mix.shell.cmd("lsof -wni tcp:#{epmd_port} -t | xargs kill -9")
end
defp start_tunnel!(remote_host, app_port, epmd_port) do
spawn(fn ->
Mix.shell.info("# Setting up SSH tunnel..")
Mix.shell.cmd("ssh -L #{app_port}:localhost:#{app_port} -L #{epmd_port}:localhost:#{epmd_port} #{remote_host} -f -N")
end)
end
defp start_observer!(erlang_cookie) do
Mix.shell.info("# Starting observer..")
Mix.shell.info("\n\n==> Connect to node \"#{erlang_cookie}@127.0.0.1\" by using the UI\n\n")
Mix.shell.cmd("erl -name debug@127.0.0.1 -setcookie #{erlang_cookie} -run observer")
end
end