proxMon/server/lib/server/metrics.ex

48 lines
1.4 KiB
Elixir

defmodule Server.Metrics do
@moduledoc "Metric sample storage and retrieval."
import Ecto.Query
alias Server.Repo
alias Server.Schema.Metric
@spec record_sample(integer(), String.t(), DateTime.t(), map()) ::
{:ok, Metric.t()} | {:error, Ecto.Changeset.t()}
def record_sample(host_id, interval_type, collected_at, payload) do
changeset =
Metric.changeset(%Metric{}, %{
host_id: host_id,
interval_type: interval_type,
collected_at: collected_at,
payload: payload
})
with %Ecto.Changeset{valid?: true} = cs <- changeset,
true <- host_exists?(host_id) || {:host_missing, cs} do
Repo.insert(cs)
else
%Ecto.Changeset{} = cs -> {:error, cs}
{:host_missing, cs} -> {:error, Ecto.Changeset.add_error(cs, :host, "does not exist")}
end
end
defp host_exists?(host_id) do
Repo.exists?(from(h in Server.Schema.Host, where: h.id == ^host_id))
end
@spec latest_sample(integer(), String.t()) :: Metric.t() | nil
def latest_sample(host_id, interval_type) do
from(m in Metric,
where: m.host_id == ^host_id and m.interval_type == ^interval_type,
order_by: [desc: m.collected_at],
limit: 1
)
|> Repo.one()
end
@spec delete_older_than(DateTime.t()) :: {non_neg_integer(), nil}
def delete_older_than(%DateTime{} = cutoff) do
from(m in Metric, where: m.collected_at < ^cutoff)
|> Repo.delete_all()
end
end