Add basic metrics
This commit is contained in:
parent
e7211d2042
commit
757c2b696a
|
@ -14,9 +14,11 @@ defmodule Wiki.Application do
|
|||
# Start the PubSub system
|
||||
{Phoenix.PubSub, name: Wiki.PubSub},
|
||||
# Start the Endpoint (http/https)
|
||||
WikiWeb.Endpoint
|
||||
WikiWeb.Endpoint,
|
||||
# Start a worker by calling: Wiki.Worker.start_link(arg)
|
||||
# {Wiki.Worker, arg}
|
||||
{Wiki.MetricStorage, WikiWeb.Telemetry.metrics()},
|
||||
Wiki.MetricGenerator
|
||||
]
|
||||
|
||||
# See https://hexdocs.pm/elixir/Supervisor.html
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
defmodule Wiki.MetricGenerator do
|
||||
use GenServer
|
||||
alias Wiki.Repo
|
||||
alias Wiki.Content.{Page, PageLink, Upload}
|
||||
|
||||
def start_link(state) do
|
||||
GenServer.start_link(__MODULE__, state, name: __MODULE__)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(state) do
|
||||
update_metrics()
|
||||
|
||||
# 5 minutes
|
||||
Process.send_after(self(), :update, 5 * 60 * 1000)
|
||||
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info(:update, state) do
|
||||
update_metrics()
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
def update_metrics do
|
||||
pages = Repo.aggregate(Page, :count)
|
||||
uploads = Repo.aggregate(Upload, :count)
|
||||
links = Repo.aggregate(PageLink, :count)
|
||||
:telemetry.execute([:wiki, :pages], %{count: pages})
|
||||
:telemetry.execute([:wiki, :uploads], %{count: uploads})
|
||||
:telemetry.execute([:wiki, :links], %{count: links})
|
||||
end
|
||||
end
|
|
@ -0,0 +1,66 @@
|
|||
defmodule Wiki.MetricStorage do
|
||||
use GenServer
|
||||
|
||||
@history_buffer_size 50
|
||||
|
||||
def metrics_history(metric) do
|
||||
GenServer.call(__MODULE__, {:data, metric})
|
||||
end
|
||||
|
||||
def start_link(args) do
|
||||
GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(metrics) do
|
||||
Process.flag(:trap_exit, true)
|
||||
|
||||
metric_histories_map =
|
||||
metrics
|
||||
|> Enum.map(fn metric ->
|
||||
attach_handler(metric)
|
||||
{metric, CircularBuffer.new(@history_buffer_size)}
|
||||
end)
|
||||
|> Map.new()
|
||||
|
||||
{:ok, metric_histories_map}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def terminate(_, metrics) do
|
||||
for metric <- metrics do
|
||||
:telemetry.detach({__MODULE__, metric, self()})
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
defp attach_handler(%{event_name: name_list} = metric) do
|
||||
:telemetry.attach(
|
||||
{__MODULE__, metric, self()},
|
||||
name_list,
|
||||
&__MODULE__.handle_event/4,
|
||||
metric
|
||||
)
|
||||
end
|
||||
|
||||
def handle_event(_event_name, data, metadata, metric) do
|
||||
if data = Phoenix.LiveDashboard.extract_datapoint_for_metric(metric, data, metadata) do
|
||||
GenServer.cast(__MODULE__, {:telemetry_metric, data, metric})
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_cast({:telemetry_metric, data, metric}, state) do
|
||||
{:noreply, update_in(state[metric], &CircularBuffer.insert(&1, data))}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call({:data, metric}, _from, state) do
|
||||
if history = state[metric] do
|
||||
{:reply, CircularBuffer.to_list(history), state}
|
||||
else
|
||||
{:reply, [], state}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -56,7 +56,9 @@ defmodule WikiWeb.Router do
|
|||
scope "/", WikiWeb do
|
||||
pipe_through [:browser, :require_authenticated_user, :require_admin_user]
|
||||
|
||||
live_dashboard "/dashboard", metrics: WikiWeb.Telemetry
|
||||
live_dashboard "/dashboard",
|
||||
metrics: WikiWeb.Telemetry,
|
||||
metrics_history: {Wiki.MetricStorage, :metrics_history, []}
|
||||
end
|
||||
|
||||
scope "/", WikiWeb do
|
||||
|
|
|
@ -21,6 +21,11 @@ defmodule WikiWeb.Telemetry do
|
|||
|
||||
def metrics do
|
||||
[
|
||||
# Wiki Metrics
|
||||
last_value("wiki.pages.count"),
|
||||
last_value("wiki.uploads.count"),
|
||||
last_value("wiki.links.count"),
|
||||
|
||||
# Phoenix Metrics
|
||||
summary("phoenix.endpoint.stop.duration",
|
||||
unit: {:native, :millisecond}
|
||||
|
|
3
mix.exs
3
mix.exs
|
@ -47,7 +47,8 @@ defmodule Wiki.MixProject do
|
|||
{:jason, "~> 1.0"},
|
||||
{:plug_cowboy, "~> 2.0"},
|
||||
{:phx_gen_auth, "~> 0.4.0", only: :dev, runtime: false},
|
||||
{:earmark, "~> 1.4.10"}
|
||||
{:earmark, "~> 1.4.10"},
|
||||
{:circular_buffer, "~> 0.3.0"}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
1
mix.lock
1
mix.lock
|
@ -1,6 +1,7 @@
|
|||
%{
|
||||
"argon2_elixir": {:hex, :argon2_elixir, "2.3.0", "e251bdafd69308e8c1263e111600e6d68bd44f23d2cccbe43fcb1a417a76bc8e", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "28ccb63bff213aecec1f7f3dde9648418b031f822499973281d8f494b9d5a3b3"},
|
||||
"bcrypt_elixir": {:hex, :bcrypt_elixir, "2.2.0", "3df902b81ce7fa8867a2ae30d20a1da6877a2c056bfb116fd0bc8a5f0190cea4", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "762be3fcb779f08207531bc6612cca480a338e4b4357abb49f5ce00240a77d1e"},
|
||||
"circular_buffer": {:hex, :circular_buffer, "0.3.0", "3eaa7e349ab07cff53dd1c25eb179ac14913fe1e407762260402a291dac4af96", [:mix], [], "hexpm", "f582b2ce394f8965cadf43c5b140f399b83dc8404aef701cb41c928c4bac1943"},
|
||||
"comeonin": {:hex, :comeonin, "5.3.1", "7fe612b739c78c9c1a75186ef2d322ce4d25032d119823269d0aa1e2f1e20025", [:mix], [], "hexpm", "d6222483060c17f0977fad1b7401ef0c5863c985a64352755f366aee3799c245"},
|
||||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
|
||||
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
|
||||
|
|
Loading…
Reference in New Issue