[#6] adding some documentation in the modules
This commit is contained in:
parent
edc2e949cf
commit
41311bc857
|
@ -1,6 +1,7 @@
|
|||
/_build
|
||||
/cover
|
||||
/deps
|
||||
/doc
|
||||
erl_crash.dump
|
||||
*.ez
|
||||
*.beam
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
|
||||
**TODO: Add description**
|
||||
|
||||
## Documentation
|
||||
|
||||
In order to create the documentation
|
||||
|
||||
```
|
||||
mix docs
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
POAAgent is an Elixir application, in order to run it first we need to fetch the dependencies and compile it.
|
||||
|
|
|
@ -5,7 +5,7 @@ use Mix.Config
|
|||
config :poa_agent,
|
||||
:collectors,
|
||||
[
|
||||
# {:my_collector, POAAgent.Plugins.Collectors.MyCollector, :my_metrics, [host: "localhost", port: 1234]}
|
||||
# {:my_collector, POAAgent.Plugins.Collectors.MyCollector, 1000, :my_metrics, [host: "localhost", port: 1234]}
|
||||
]
|
||||
|
||||
# configuration for transfers. The format for each collector is {collector_process_id, module, args}
|
||||
|
@ -20,4 +20,4 @@ config :poa_agent,
|
|||
:mappings,
|
||||
[
|
||||
# {:my_collector, [:my_transfer]}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
defmodule POAAgent.Application do
|
||||
@moduledoc false
|
||||
@moduledoc """
|
||||
|
||||
This module implements the Application behaviour
|
||||
|
||||
"""
|
||||
|
||||
use Application
|
||||
|
||||
|
@ -14,4 +18,4 @@ defmodule POAAgent.Application do
|
|||
opts = [strategy: :one_for_one, name: POAAgent.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +1,104 @@
|
|||
defmodule POAAgent.Plugins.Collector do
|
||||
|
||||
@moduledoc """
|
||||
Defines a Collector Plugin.
|
||||
|
||||
A Collector plugin will run in an independent process and will run the `collect/1`
|
||||
function in a given `frequency`.
|
||||
|
||||
`POAAgent` app reads the Collectors configuration from the `config.exs` file when bootstrap and will create a
|
||||
process per each one of them. That configuration is referenced by :collectors key.
|
||||
|
||||
config :poa_agent,
|
||||
:collectors,
|
||||
[
|
||||
{name, module, frequency, label, args}
|
||||
]
|
||||
|
||||
for example
|
||||
|
||||
config :poa_agent,
|
||||
:collectors,
|
||||
[
|
||||
{:my_collector, POAAgent.Plugins.Collectors.MyCollector, 5000, :my_metrics, [host: "localhost", port: 1234]}
|
||||
]
|
||||
|
||||
`name`, `module`, `frequency`, `label` and `args` must be defined in the configuration file.
|
||||
|
||||
- `name`: Name for the new created process. Must be unique
|
||||
- `module`: Module which implements the Collector behaviour
|
||||
- `frequency`: time in milliseconds after which the function `collect/1` will be called
|
||||
- `label`: The data collected will be prefixed with this label. ie `{:eth_metrics, "data"}`
|
||||
- `args`: Initial args which will be passed to the `init_collector/1` function
|
||||
|
||||
In order to work properly we have to define in the configuration file also the mapping between the Collector
|
||||
and the Transfers related with it. A `Transfer` is a Plugin process which transfers the data to outside the agent node
|
||||
(external Database, Dashboard server...).
|
||||
|
||||
config :poa_agent,
|
||||
:mappings,
|
||||
[
|
||||
{collector_name, [transfer_name1, transfer_name2]}
|
||||
]
|
||||
|
||||
for example
|
||||
|
||||
config :poa_agent,
|
||||
:mappings,
|
||||
[
|
||||
{:my_collector, [:my_transfer]}
|
||||
]
|
||||
|
||||
In order to implement your Collector Plugin you must implement 3 functions.
|
||||
|
||||
- `init_collector/1`: Called only once when the process starts
|
||||
- `collect/1`: This function is called periodically after `frequency` milliseconds. It is responsible
|
||||
of retrieving the metrics
|
||||
- `terminate/1`: Called just before stopping the process
|
||||
|
||||
This is a simple example of custom Collector Plugin
|
||||
|
||||
defmodule POAAgent.Plugins.Collectors.MyCollector do
|
||||
use POAAgent.Plugins.Collector
|
||||
|
||||
def init_collector(args) do
|
||||
{:ok, :no_state}
|
||||
end
|
||||
|
||||
def collect(:no_state) do
|
||||
IO.puts "I am collecting data!"
|
||||
{:ok, "data retrieved", :no_state}
|
||||
end
|
||||
|
||||
def terminate(_reason, _state) do
|
||||
:ok
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
"""
|
||||
|
||||
@doc """
|
||||
A callback executed when the Collector Plugin starts.
|
||||
The argument is retrieved from the configuration file when the Collector is defined
|
||||
It must return `{:ok, state}`, that `state` will be keept as in `GenServer` and can be
|
||||
retrieved in the `collect/1` function.
|
||||
"""
|
||||
@callback init_collector(args :: term()) ::
|
||||
{:ok, any()}
|
||||
|
||||
@doc """
|
||||
In this callback is where the metrics collection logic must be placed.
|
||||
It must return `{:ok, data, state}`. `data` is the retrieved metrics.
|
||||
"""
|
||||
@callback collect(state :: any()) :: {:ok, data :: any(), state :: any()}
|
||||
|
||||
@doc """
|
||||
This callback is called just before the Process goes down. This is a good place for closing connections.
|
||||
"""
|
||||
@callback terminate(state :: term()) :: term()
|
||||
|
||||
@doc false
|
||||
defmacro __using__(_opt) do
|
||||
quote do
|
||||
@behaviour POAAgent.Plugins.Collector
|
||||
|
@ -19,7 +111,7 @@ defmodule POAAgent.Plugins.Collector do
|
|||
@doc false
|
||||
def init(state) do
|
||||
{:ok, internal_state} = init_collector(state[:args])
|
||||
set_collector_timer()
|
||||
set_collector_timer(state.frequency)
|
||||
{:ok, Map.put(state, :internal_state, internal_state)}
|
||||
end
|
||||
|
||||
|
@ -32,7 +124,7 @@ defmodule POAAgent.Plugins.Collector do
|
|||
def handle_info(:collect, state) do
|
||||
{:ok, data, internal_state} = collect(state.internal_state)
|
||||
transfer(data, state.label, state.transfers)
|
||||
set_collector_timer()
|
||||
set_collector_timer(state.frequency)
|
||||
{:noreply, %{state | internal_state: internal_state}}
|
||||
end
|
||||
def handle_info(_msg, state) do
|
||||
|
@ -61,8 +153,8 @@ defmodule POAAgent.Plugins.Collector do
|
|||
end
|
||||
|
||||
@doc false
|
||||
defp set_collector_timer() do
|
||||
Process.send_after(self(), :collect, 5000) # TODO timeout must be configurable
|
||||
defp set_collector_timer(frequency) do
|
||||
Process.send_after(self(), :collect, frequency)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,8 +12,8 @@ defmodule POAAgent.Plugins.Collectors.Supervisor do
|
|||
collectors = Application.get_env(:poa_agent, :collectors)
|
||||
mappings = Application.get_env(:poa_agent, :mappings)
|
||||
|
||||
children = for {name, module, label, args} <- collectors do
|
||||
worker(module, [%{name: name, transfers: mappings[name], label: label, args: args}])
|
||||
children = for {name, module, frequency, label, args} <- collectors do
|
||||
worker(module, [%{name: name, transfers: mappings[name], frequency: frequency, label: label, args: args}])
|
||||
end
|
||||
|
||||
opts = [strategy: :one_for_one]
|
||||
|
|
|
@ -1,12 +1,87 @@
|
|||
defmodule POAAgent.Plugins.Transfer do
|
||||
|
||||
@moduledoc """
|
||||
Defines a Transfer Plugin.
|
||||
|
||||
A Transfer plugin receives data from Collectors. It uses the Collector's `label` in order to
|
||||
differenciate from multiple Collectors.
|
||||
|
||||
`POAAgent` app reads the Transfers configuration from the `config.exs` file when bootstrap and will create a
|
||||
process per each one of them. That configuration is referenced by :transfers key.
|
||||
|
||||
config :poa_agent,
|
||||
:transfers,
|
||||
[
|
||||
{name, module, args}
|
||||
]
|
||||
|
||||
for example
|
||||
|
||||
config :poa_agent,
|
||||
:transfers,
|
||||
[
|
||||
{:my_transfer, POAAgent.Plugins.Transfers.MyTransfer, [ws_key: "mykey", other_stuff: "hello"]}
|
||||
]
|
||||
|
||||
`name`, `module` and `args` must be defined in the configuration file.
|
||||
|
||||
- `name`: Name for the new created process. Must be unique
|
||||
- `module`: Module which implements the Transfer behaviour
|
||||
- `args`: Initial args which will be passed to the `init_transfer/1` function
|
||||
|
||||
In order to implement your Transfer Plugin you must implement 3 functions.
|
||||
|
||||
- `init_transfer/1`: Called only once when the process starts
|
||||
- `data_received/2`: This function is called every time a Collector sends metrics to the Transfer
|
||||
- `terminate/1`: Called just before stopping the process
|
||||
|
||||
This is a simple example of custom Transfer Plugin
|
||||
|
||||
defmodule POAAgent.Plugins.Transfers.MyTransfer do
|
||||
use POAAgent.Plugins.Transfer
|
||||
|
||||
def init_transfer(args) do
|
||||
{:ok, :no_state}
|
||||
end
|
||||
|
||||
def data_received(label, data, state) do
|
||||
IO.puts "Received data from the collector referenced by label"
|
||||
{:ok, :no_state}
|
||||
end
|
||||
|
||||
def terminate(_reason, _state) do
|
||||
:ok
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
"""
|
||||
|
||||
@doc """
|
||||
A callback executed when the Transfer Plugin starts.
|
||||
The argument is retrieved from the configuration file when the Transfer is defined
|
||||
It must return `{:ok, state}`, that `state` will be keept as in `GenServer` and can be
|
||||
retrieved in the `data_received/2` function.
|
||||
"""
|
||||
@callback init_transfer(args :: term()) ::
|
||||
{:ok, any()}
|
||||
|
||||
@doc """
|
||||
In this callback is called when a Collector sends data to this Transfer.
|
||||
|
||||
The data received is in `{label, data}` format where `label` identifies the Collector and the
|
||||
data is the real data received.
|
||||
|
||||
It must return `{:ok, state}`.
|
||||
"""
|
||||
@callback data_received(label :: atom(), data :: any(), state :: any()) :: {:ok, any()}
|
||||
|
||||
@doc """
|
||||
This callback is called just before the Process goes down. This is a good place for closing connections.
|
||||
"""
|
||||
@callback terminate(state :: term()) :: term()
|
||||
|
||||
@doc false
|
||||
defmacro __using__(_opt) do
|
||||
quote do
|
||||
@behaviour POAAgent.Plugins.Transfer
|
||||
|
|
27
mix.exs
27
mix.exs
|
@ -1,13 +1,16 @@
|
|||
defmodule POAAgent.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
@version "0.1.0"
|
||||
|
||||
def project do
|
||||
[
|
||||
app: :poa_agent,
|
||||
version: "0.1.0",
|
||||
version: @version,
|
||||
elixir: "~> 1.6",
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps()
|
||||
deps: deps(),
|
||||
docs: docs()
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -21,7 +24,25 @@ defmodule POAAgent.MixProject do
|
|||
defp deps do
|
||||
[
|
||||
{:credo, "~> 0.9", only: [:dev, :test], runtime: false},
|
||||
{:dialyxir, "~> 0.5", only: [:dev], runtime: false}
|
||||
{:dialyxir, "~> 0.5", only: [:dev], runtime: false},
|
||||
|
||||
# Docs
|
||||
{:ex_doc, "~> 0.18", only: :dev, runtime: false}
|
||||
]
|
||||
end
|
||||
|
||||
defp docs do
|
||||
[
|
||||
source_ref: "v#{@version}",
|
||||
main: "POAAgent.Application",
|
||||
source_url: "https://github.com/poanetwork/poa-netstats-agent",
|
||||
groups_for_modules: [
|
||||
"Plugins": [
|
||||
POAAgent.Plugins.Collector,
|
||||
POAAgent.Plugins.Transfer,
|
||||
]
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -2,5 +2,7 @@
|
|||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [], [], "hexpm"},
|
||||
"credo": {:hex, :credo, "0.9.2", "841d316612f568beb22ba310d816353dddf31c2d94aa488ae5a27bb53760d0bf", [], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [], [], "hexpm"},
|
||||
"earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [], [], "hexpm"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"},
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ defmodule POAAgent.PluginsTest do
|
|||
end
|
||||
end
|
||||
|
||||
assert Collector1.init(%{}) == {:ok, %{internal_state: :no_state}}
|
||||
assert Collector1.init(%{frequency: 5_000}) == {:ok, %{internal_state: :no_state, frequency: 5_000}}
|
||||
assert Collector1.handle_call(:msg, :from, :state) == {:noreply, :state}
|
||||
assert Collector1.handle_info(:msg, :state) == {:noreply, :state}
|
||||
assert Collector1.handle_cast(:msg, :state) == {:noreply, :state}
|
||||
|
@ -92,7 +92,7 @@ defmodule POAAgent.PluginsTest do
|
|||
transfer1 = :transfer2
|
||||
|
||||
{:ok, tpid} = Transfer2.start_link(%{name: transfer1, args: self()})
|
||||
{:ok, cpid} = Collector2.start_link(%{name: :collector2, transfers: [transfer1], label: :label, args: self()})
|
||||
{:ok, cpid} = Collector2.start_link(%{name: :collector2, transfers: [transfer1], label: :label, args: self(), frequency: 2_000})
|
||||
|
||||
assert_receive {:sent, ^cpid, "data retrieved"}, 20_000
|
||||
assert_receive {:received, ^tpid, :label, "data retrieved"}, 20_000
|
||||
|
|
Loading…
Reference in New Issue