63 lines
1.6 KiB
Elixir
63 lines
1.6 KiB
Elixir
defmodule HAHandler.HAProxy do
|
|
alias :procket, as: Socket
|
|
|
|
@haproxy_socket "/run/haproxy.sock"
|
|
|
|
def open_socket() do
|
|
pad = 8 * (Socket.unix_path_max() - byte_size(@haproxy_socket))
|
|
|
|
sockaddr =
|
|
Socket.sockaddr_common(1, byte_size(@haproxy_socket)) <> @haproxy_socket <> <<0::size(pad)>>
|
|
|
|
family = 1
|
|
|
|
{:ok, socket} = Socket.socket(family, 1, 0)
|
|
|
|
case Socket.connect(socket, sockaddr) do
|
|
:ok ->
|
|
{stdin, stdout} = {socket, socket}
|
|
port = Port.open({:fd, stdin, stdout}, [{:line, 10_000}, :binary])
|
|
Process.link(port)
|
|
|
|
{:ok, port}
|
|
|
|
{:error, err} ->
|
|
{:error, err}
|
|
end
|
|
end
|
|
|
|
defp read_from_socket(socket, acc \\ "") do
|
|
receive do
|
|
{_port, {:data, {:noeol, data}}} ->
|
|
read_from_socket(socket, acc <> data)
|
|
{_port, {:data, {:eol, data}}} ->
|
|
Poison.decode(acc <> data)
|
|
_ ->
|
|
{:error, :unexpected}
|
|
after 5000 ->
|
|
{:error, :timeout}
|
|
end
|
|
end
|
|
|
|
def get_stats() do
|
|
case open_socket() do
|
|
{:ok, socket} ->
|
|
send socket, {self(), {:command, "show stat json\n"}}
|
|
case read_from_socket(socket) do
|
|
{:ok, raw} ->
|
|
for entry <- raw do
|
|
attrs = entry
|
|
|> Enum.filter(fn m -> get_in(m, ["field", "name"]) == "pxname" end)
|
|
|> Enum.at(0)
|
|
|
|
%{type: attrs |> Map.get("objType"), name: get_in(attrs, ["value", "value"])}
|
|
end
|
|
|
|
{:error, err} ->
|
|
{:error, err}
|
|
end
|
|
{:error, err} -> {:error, err}
|
|
end
|
|
end
|
|
end
|