add many stuff owo

This commit is contained in:
Luna Mendes 2018-06-11 04:24:16 -03:00
parent 4bce1c0146
commit 62e636cfe7
9 changed files with 208 additions and 3 deletions

31
config/config.example.exs Normal file
View File

@ -0,0 +1,31 @@
use Mix.Config
config :elstat,
# where will elstat (backend and frontend)
# be served
port: 8069,
# which services will be managed by elstat?
# this follows a service spec
# the example here is for elixire
services: [
%{
id: :elixire,
description: "elixi.re",
adapter: Elstat.Adapter.Elixire,
adapter_opts: %{
base_url: "https://elixi.re",
},
# every 10 seconds
poll: 10,
},
%{
id: :genserver,
description: "genserver, elixire main server",
adapter: Elstat.Adapter.Ping,
adapter_opts: %{
address: "192.168.1.1",
},
poll: 15,
},
]

View File

@ -1,4 +1,29 @@
use Mix.Config
config :elstat,
port: 8069
port: 8069,
# which services will be managed by elstat?
# this follows a service spec
# the example here is for elixire
services: [
%{
id: :elixire,
human_id: "elixi.re",
adapter: Elstat.Adapter.Elixire,
adapter_opts: %{
base_url: "https://elixi.re",
},
# every 10 seconds
poll: 10,
},
%{
id: :genserver,
human_id: "genserver, elixire main server",
adapter: Elstat.Adapter.Ping,
adapter_opts: %{
address: "192.168.1.1",
},
poll: 15,
},
]

7
lib/adapters/adapter.ex Normal file
View File

@ -0,0 +1,7 @@
defmodule Elstat.Adapter do
@type adapter_check_res :: {:ok, any()} | {:error, any()}
@type adp_args :: Map.t
@callback check(adp_args) :: adapter_check_res
end

31
lib/adapters/elixire.ex Normal file
View File

@ -0,0 +1,31 @@
defmodule Elstat.Adapter.Elixire do
@behaviour Elstat.Adapter
use GenServer
require Logger
def start_link(service_opts) do
GenServer.start_link(__MODULE__, service_opts, [])
end
def init(service_opts) do
Logger.info("Elixire adapter started with #{inspect service_opts}")
{:ok, %{}}
end
def check(args) do
addr = args.base_url
req_start = :erlang.monotonic_time(:millisecond)
resp = HTTPoison.get!("#{addr}/api/hello")
req_end = :erlang.monotonic_time(:millisecond)
delta = req_end - req_start
{:ok, {:map, %{
status: resp.status_code == 200,
latency: {:millisecond, delta},
}}}
end
end

22
lib/adapters/ping.ex Normal file
View File

@ -0,0 +1,22 @@
defmodule Elstat.Adapter.Ping do
@behaviour Elstat.Adapter
use GenServer
require Logger
def start_link(service_opts) do
GenServer.start_link(__MODULE__, service_opts, [])
end
def init(service_opts) do
Logger.info("Ping started with #{inspect service_opts}")
{:ok, %{}}
end
def check(args) do
{cmd_output, _} = System.cmd("ping", ["-c", "1", args.address])
alive? = not Regex.match?(~r/100(\.0)?% packet loss/, cmd_output)
{:ok, {:bool, alive?}}
end
end

80
lib/manager.ex Normal file
View File

@ -0,0 +1,80 @@
defmodule Elstat.Error.Service do
defexception message: "default message"
end
defmodule Elstat.ServiceWorker do
require Logger
def start_link(service) do
Logger.info "spawning worker for #{inspect service.id}"
worker_pid = spawn(fn ->
worker_func(service)
end)
{:ok, worker_pid}
end
def worker_func(service) do
adapter = service.adapter
result = adapter.check(service.adapter_opts)
Logger.info "result from #{inspect adapter} #{inspect service.id}: #{inspect result}"
man_pid = :global.whereis_name Elstat.Manager
send man_pid, {:service_info, {service.id, result}}
Process.sleep(service.poll * 1000)
worker_func(service)
end
end
defmodule Elstat.Manager do
@moduledoc """
Elstat's service manager.
"""
use GenServer
require Logger
def start_link(opts) do
GenServer.start_link(__MODULE__, :ok, [name: {:global, Elstat.Manager}] ++ opts)
end
def build_services() do
services = Application.fetch_env!(:elstat, :services)
workers = services
|> Enum.map(fn service ->
service_id = service.id
# each service worker will enter an infinite loop
# polling the service (via an adapter) and giving
# information back to the manager, so it can
# process and show those via its API.
%{
id: service_id,
start: {Elstat.ServiceWorker, :start_link, [service]}
}
end)
# spawn the managere alongside service workers
[ Elstat.Manager | workers]
end
# server callbacks
def init(:ok) do
services = Application.fetch_env!(:elstat, :services)
# TODO : send data to db
{:ok, %{
services: services,
}}
end
def handle_info({:service_info, data}, state) do
Logger.debug "got service data! #{inspect data}"
{:noreply, state}
end
end

View File

@ -9,13 +9,18 @@ defmodule Elstat.Supervisor do
def init(:ok) do
Logger.info "starting sup"
children = [
base_children = [
%{
id: Elstat.Cowboy,
start: {Elstat.Cowboy, :start_link, []},
}
},
{Sqlitex.Server, ['elstat.db', [name: Sqlitex.Server]]}
]
service_children = Elstat.Manager.build_services()
children = service_children ++ base_children
Logger.debug "final children #{inspect children}"
Supervisor.init(children, strategy: :one_for_one)
end

View File

@ -23,6 +23,7 @@ defmodule Elstat.MixProject do
defp deps do
[
{:httpoison, "~> 1.1.1"},
{:sqlitex, "~> 1.4.2"},
{:cowboy, "~> 2.4.0"}
]
end

View File

@ -2,6 +2,8 @@
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"cowboy": {:hex, :cowboy, "2.4.0", "f1b72fabe9c8a5fc64ac5ac85fb65474d64733d1df52a26fad5d4ba3d9f70a9f", [:rebar3], [{:cowlib, "~> 2.3.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.5.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "2.3.0", "bbd58ef537904e4f7c1dd62e6aa8bc831c8183ce4efa9bd1150164fe15be4caa", [:rebar3], [], "hexpm"},
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
"esqlite": {:hex, :esqlite, "0.2.4", "3a8a352c190afe2d6b828b252a6fbff65b5cc1124647f38b15bdab3bf6fd4b3e", [:rebar3], [], "hexpm"},
"hackney": {:hex, :hackney, "1.12.1", "8bf2d0e11e722e533903fe126e14d6e7e94d9b7983ced595b75f532e04b7fdc7", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"httpoison": {:hex, :httpoison, "1.1.1", "96ed7ab79f78a31081bb523eefec205fd2900a02cda6dbc2300e7a1226219566", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.1", "cbc3b2fa1645113267cc59c760bafa64b2ea0334635ef06dbac8801e42f7279c", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
@ -9,6 +11,7 @@
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"},
"ranch": {:hex, :ranch, "1.5.0", "f04166f456790fee2ac1aa05a02745cc75783c2bfb26d39faf6aefc9a3d3a58a", [:rebar3], [], "hexpm"},
"sqlitex": {:hex, :sqlitex, "1.4.2", "b18f2b53cefbc9cca0bd17d51386f9caa7cf341144cb314e5cd9fd2a1f9b0845", [:mix], [{:decimal, "~> 1.1", [hex: :decimal, repo: "hexpm", optional: false]}, {:esqlite, "~> 0.2.4", [hex: :esqlite, repo: "hexpm", optional: false]}], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
}