Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#73] adding system metric collector
- Loading branch information
Showing
8 changed files
with
192 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
defmodule POAAgent.Entity.System.Statistics do | ||
@moduledoc false | ||
|
||
alias POAAgent.Format.POAProtocol.Data | ||
|
||
@type t :: %__MODULE__{ | ||
cpu_load: number, | ||
memory_usage: number, | ||
disk_usage: number | ||
} | ||
|
||
defstruct [ | ||
cpu_load: 0, | ||
memory_usage: 0, | ||
disk_usage: 0 | ||
] | ||
|
||
def new(cpu_load, memory_usage, disk_usage) do | ||
%__MODULE__{ | ||
cpu_load: cpu_load, | ||
memory_usage: memory_usage, | ||
disk_usage: disk_usage | ||
} | ||
end | ||
|
||
defimpl POAAgent.Entity.NameConvention do | ||
def from_elixir_to_node(x) do | ||
Map.from_struct(x) | ||
end | ||
end | ||
|
||
defimpl Data.Format do | ||
def to_data(x) do | ||
Data.new("statistics", x) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
defmodule POAAgent.Plugins.Collectors.System.Stats do | ||
use POAAgent.Plugins.Collector | ||
|
||
@moduledoc """ | ||
This module retrieves system metrics. Those metrics are the cpu usage, memory and disk. | ||
In order to use it we have to add it to the config file like this: | ||
{:system_collector, POAAgent.Plugins.Collectors.System.Stats, 60_000, :system_metrics, []} | ||
In this example we are checking the system metrics every minute | ||
""" | ||
|
||
alias POAAgent.Entity.System.Statistics | ||
|
||
@typep internal_state :: %{ | ||
last_metrics: Statistics.t | ||
} | ||
|
||
@doc false | ||
@spec init_collector(term()) :: {:ok, internal_state()} | ||
def init_collector(_) do | ||
stats = gather_metrics() | ||
|
||
{:transfer, stats, %{last_metrics: stats}} | ||
end | ||
|
||
@doc false | ||
@spec collect(internal_state()) :: term() | ||
def collect(%{last_metrics: last_metrics} = state) do | ||
case gather_metrics() do | ||
^last_metrics -> | ||
{:notransfer, state} | ||
metrics -> | ||
{:transfer, metrics, %{state | last_metrics: metrics}} | ||
end | ||
end | ||
|
||
@doc false | ||
@spec metric_type() :: String.t | ||
def metric_type do | ||
"system_metrics" | ||
end | ||
|
||
@doc false | ||
@spec terminate(internal_state()) :: :ok | ||
def terminate(_state) do | ||
:ok | ||
end | ||
|
||
defp gather_metrics() do | ||
Statistics.new(cpu_load(), memory_usage(), disk_usage()) | ||
end | ||
|
||
defp cpu_load do | ||
{total, amount} = | ||
case :cpu_sup.util([:per_cpu]) do | ||
cpu_info when is_list(cpu_info) -> | ||
cpu_info | ||
|> Enum.reduce({0, 0}, fn({_, load, _, _}, {total, acc}) -> | ||
{total + 100.0, acc + load} | ||
end) | ||
_ -> | ||
{100, 0} | ||
end | ||
|
||
percentage(total, amount) | ||
end | ||
|
||
defp memory_usage do | ||
memory = :memsup.get_system_memory_data() | ||
|
||
{total, amount} = | ||
case Keyword.get(memory, :total_memory) do | ||
nil -> | ||
{100, 0} | ||
total_memory -> | ||
{total_memory, :erlang.memory(:total)} | ||
end | ||
|
||
percentage(total, amount) | ||
end | ||
|
||
defp disk_usage do | ||
[{_, _, usage} | _] = :disksup.get_disk_data() |> Enum.sort(&(elem(&1, 2) >= elem(&2, 2))) | ||
usage | ||
end | ||
|
||
defp percentage(total, amount) do | ||
100 * amount / total | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
defmodule POAAgent.Plugins.Collectors.System.StatsTest do | ||
use ExUnit.Case | ||
|
||
alias POAAgent.Plugins.Collectors.System.Stats | ||
alias POAAgent.Entity.System.Statistics | ||
|
||
test "sending stats to the transfer when the collector starts and after a while" do | ||
echo_transfer = :echo_transfer | ||
{:ok, _echo} = EchoTransfer.start(echo_transfer) | ||
|
||
args = %{ | ||
name: :system_metrics, | ||
transfers: [echo_transfer], | ||
frequency: 1000, | ||
label: :system_metrics, | ||
args: [] | ||
} | ||
|
||
{:ok, _pid} = Stats.start_link(args) | ||
|
||
assert_receive {:system_metrics, metric}, 20_000 | ||
assert %Statistics{cpu_load: cpu_load, memory_usage: memory_usage, disk_usage: disk_usage} = metric | ||
assert is_number(cpu_load) | ||
assert is_number(memory_usage) | ||
assert is_number(disk_usage) | ||
|
||
# we should receiver system metrics again | ||
assert_receive {:system_metrics, metric}, 20_000 | ||
assert %Statistics{cpu_load: cpu_load, memory_usage: memory_usage, disk_usage: disk_usage} = metric | ||
assert is_number(cpu_load) | ||
assert is_number(memory_usage) | ||
assert is_number(disk_usage) | ||
end | ||
end |