diff --git a/lib/adapters/elixire.ex b/lib/adapters/elixire.ex index ccc5d1d..8e9bd18 100644 --- a/lib/adapters/elixire.ex +++ b/lib/adapters/elixire.ex @@ -3,7 +3,7 @@ defmodule Elstat.Adapter.Elixire do def adapter_spec do %{ - db_columns: [:status, :latency] + db_columns: [:timestamp, :status, :latency] } end @@ -21,5 +21,9 @@ defmodule Elstat.Adapter.Elixire do latency: delta, }}} end + + def transform_val({:map, %{status: status, latency: latency}}) do + [status, latency] + end end diff --git a/lib/adapters/ping.ex b/lib/adapters/ping.ex index 6d46168..047ebf1 100644 --- a/lib/adapters/ping.ex +++ b/lib/adapters/ping.ex @@ -3,7 +3,7 @@ defmodule Elstat.Adapter.Ping do def adapter_spec do %{ - db_columns: [:status] + db_columns: [:timestamp, :status] } end @@ -12,5 +12,9 @@ defmodule Elstat.Adapter.Ping do alive? = not Regex.match?(~r/100(\.0)?% packet loss/, cmd_output) {:ok, {:bool, alive?}} end + + def transform_val({:bool, alive?}) do + [alive?] + end end diff --git a/lib/manager.ex b/lib/manager.ex index d90cfda..574f47f 100644 --- a/lib/manager.ex +++ b/lib/manager.ex @@ -64,11 +64,28 @@ defmodule Elstat.Manager do def get_current_state() do man_pid = :global.whereis_name Elstat.Manager - GenServer.call(man_pid, {:get_state}) + GenServer.call(man_pid, {:get_current}) end - + # server callbacks + + def get_columns_def do + %{ + timestamp: "timestamp bigint", + status: "status bool", + latency: "latency bigint", + } + end + + def get_columns_name do + %{ + timestamp: "timestamp", + status: "status", + latency: "latency", + } + end + def init(:ok) do services = Application.fetch_env!(:elstat, :services) @@ -81,10 +98,7 @@ defmodule Elstat.Manager do spec = adapter.adapter_spec - columns = %{ - status: "status bool", - latency: "latency bigint", - } + columns = get_columns_def() column_res = spec.db_columns |> Enum.map(fn column -> @@ -92,15 +106,8 @@ defmodule Elstat.Manager do end) |> Enum.join(",\n") - timestamp_column = if Enum.count(spec.db_columns) == 0 do - "timestamp bigint" - else - "timestamp bigint," - end - query = """ CREATE TABLE IF NOT EXISTS #{Atom.to_string service_id} ( - #{timestamp_column} #{column_res} ); """ @@ -122,7 +129,7 @@ defmodule Elstat.Manager do }} end - def handle_call({:get_state}, _from, state) do + def handle_call({:get_current}, _from, state) do reply = state.serv_state |> Map.keys |> Enum.map(fn key -> @@ -143,11 +150,49 @@ defmodule Elstat.Manager do {:reply, reply, state} end + + def build_insert_query(service_id, state) do + services = state.services + service = services[service_id] + spec = service.adapter.adapter_spec + + columns_str = spec.db_columns + |> Enum.map(fn atom -> + Atom.to_string atom + end) + |> Enum.join(",") + + query_args_str = 1..Enum.count(spec.db_columns) + |> Enum.map(fn num -> + "$#{num}" + end) + |> Enum.join(",") + + """ + INSERT INTO #{Atom.to_string service_id} (#{columns_str}) + VALUES (#{query_args_str}) + """ + end def handle_info({:service_info, {sid, sdata}}, state) do case sdata do {:ok, actual_data} -> new_serv_state = Map.put(state.serv_state, sid, actual_data) + + query = build_insert_query(sid, state) + + adapter = state.services[sid].adapter + adp_args = adapter.transform_val(actual_data) + + timestamp = :erlang.system_time(:millisecond) + + Logger.debug "query: #{query}, timestamp: #{timestamp}, adp args: #{inspect adp_args}" + + Sqlitex.with_db('elstat.db', fn(db) -> + res = Sqlitex.query(db, query, bind: [timestamp | adp_args]) + IO.puts "#{inspect res}" + end) + {:noreply, %{state | serv_state: new_serv_state}} {:error, err} -> Logger.warn "error on #{inspect sid}: #{inspect err}"