feat(server): metrics schema + context with record/latest/prune
This commit is contained in:
parent
116f1ada14
commit
687fc17082
4 changed files with 153 additions and 0 deletions
48
server/lib/server/metrics.ex
Normal file
48
server/lib/server/metrics.ex
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
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
|
||||
22
server/lib/server/schema/metric.ex
Normal file
22
server/lib/server/schema/metric.ex
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
defmodule Server.Schema.Metric do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
|
||||
@intervals ~w(fast medium slow)
|
||||
|
||||
schema "metrics" do
|
||||
belongs_to :host, Server.Schema.Host
|
||||
field :collected_at, :utc_datetime_usec
|
||||
field :interval_type, :string
|
||||
field :payload, :map
|
||||
|
||||
timestamps(type: :utc_datetime_usec, updated_at: false)
|
||||
end
|
||||
|
||||
def changeset(metric, attrs) do
|
||||
metric
|
||||
|> cast(attrs, [:host_id, :collected_at, :interval_type, :payload])
|
||||
|> validate_required([:host_id, :collected_at, :interval_type, :payload])
|
||||
|> validate_inclusion(:interval_type, @intervals)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue