Skip to content

Commit

Permalink
First pass at custom viewing metrics for simple count history, and wo…
Browse files Browse the repository at this point in the history
…rking!
  • Loading branch information
bglusman committed May 22, 2020
1 parent b9917f1 commit 5fcb503
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 4 deletions.
2 changes: 2 additions & 0 deletions lib/companies/application.ex
Expand Up @@ -12,6 +12,7 @@ defmodule Companies.Application do
Companies.Repo,
CompaniesWeb.Telemetry,
CompaniesWeb.RepoMetricsHistory,
CompaniesWeb.ViewingStats,
# Start the PubSub system
{Phoenix.PubSub, name: Companies.PubSub},
# Start the endpoint when the application starts
Expand All @@ -27,6 +28,7 @@ defmodule Companies.Application do
)

CompaniesWeb.RepoMetricsHistory.setup_handlers()
CompaniesWeb.ViewingStats.setup_handlers()

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
Expand Down
3 changes: 3 additions & 0 deletions lib/companies_web/controllers/company_controller.ex
Expand Up @@ -2,6 +2,7 @@ defmodule CompaniesWeb.CompanyController do
use CompaniesWeb, :controller

alias Companies.{Companies, Industries, Schema.Company}
import CompaniesWeb.ViewingStats, only: [telemetry_event: 0]

def recent(conn, _params) do
companies_count = Companies.count()
Expand All @@ -13,6 +14,7 @@ defmodule CompaniesWeb.CompanyController do
def index(conn, params) do
companies = Companies.all(params)
industries = Industries.for_select()
:telemetry.execute(telemetry_event(), %{company_index: 1})

render(conn, "index.html", companies: companies, industries: industries)
end
Expand All @@ -39,6 +41,7 @@ defmodule CompaniesWeb.CompanyController do

def show(conn, %{"id" => id}) do
company = Companies.get!(id, preloads: [:jobs, :industry])
:telemetry.execute(telemetry_event(), %{company_show: 1})
render(conn, "show.html", company: company)
end

Expand Down
9 changes: 9 additions & 0 deletions lib/companies_web/historical_data.ex
@@ -0,0 +1,9 @@
defmodule CompaniesWeb.HistoricalData do
alias CompaniesWeb.{RepoMetricsHistory, ViewingStats}

def signatures do
for module <- [RepoMetricsHistory, ViewingStats], reduce: %{} do
acc -> Map.merge(acc, apply(module, :signatures, []))
end
end
end
2 changes: 1 addition & 1 deletion lib/companies_web/repo_metrics_history.ex
Expand Up @@ -31,7 +31,7 @@ defmodule CompaniesWeb.RepoMetricsHistory do

def setup_handlers do
:telemetry.attach(
"aggregation-handler-generic",
"aggregation-handler-#{__MODULE__}",
@telemetry_event,
&__MODULE__.handle_event/4,
nil
Expand Down
2 changes: 1 addition & 1 deletion lib/companies_web/router.ex
Expand Up @@ -41,7 +41,7 @@ defmodule CompaniesWeb.Router do

live_dashboard "/",
metrics: CompaniesWeb.Telemetry,
historical_data: CompaniesWeb.RepoMetricsHistory.signatures()
historical_data: CompaniesWeb.HistoricalData.signatures()
end

scope "/", CompaniesWeb do
Expand Down
8 changes: 7 additions & 1 deletion lib/companies_web/telemetry.ex
Expand Up @@ -43,6 +43,12 @@ defmodule CompaniesWeb.Telemetry do
summary("ecto.dashboard.query.queue_time", unit: {:native, :millisecond}),
summary("ecto.dashboard.query.idle_time", unit: {:native, :millisecond}),

# Page view stats
summary("page_views.companies_web.company_index"),
summary("page_views.companies_web.company_show"),
summary("page_views.companies_web.job_index"),
summary("page_views.companies_web.job_show"),

# VM Metrics
summary("vm.memory.total", unit: {:byte, :kilobyte}),
summary("vm.total_run_queue_lengths.total"),
Expand All @@ -52,6 +58,6 @@ defmodule CompaniesWeb.Telemetry do
end

defp periodic_measurements do
[]
[{CompaniesWeb.ViewingStats, :emit, []}]
end
end
83 changes: 83 additions & 0 deletions lib/companies_web/viewing_stats.ex
@@ -0,0 +1,83 @@
defmodule CompaniesWeb.ViewingStats do
use GenServer

@telemetry_event [:page_views, :count_events]
@historic_metrics [:page_views, :companies_web]
@history_buffer_size 500

def signatures do
%{
@historic_metrics => {__MODULE__, :data, []}
}
end

def telemetry_event, do: @telemetry_event

def start_link([]) do
GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
end

def init(_state) do
{:ok, %{history: CircularBuffer.new(@history_buffer_size), current: %{}}}
end

def data(%{event_name: event_name} = metric) do
if List.starts_with?(event_name, @historic_metrics) do
GenServer.call(__MODULE__, {:data, metric})
else
[]
end
end

def setup_handlers do
:telemetry.attach(
"aggregation-handler-#{__MODULE__}",
@telemetry_event,
&__MODULE__.handle_event/4,
nil
)
end

def handle_event(@telemetry_event, map, metadata, config) do
GenServer.cast(__MODULE__, {:telemetry_metric, map, metadata, config})
end

def emit do
GenServer.cast(__MODULE__, :emit_telemetry)
end

def handle_call({:raw_data, _metric}, _from, %{history: history} = state) do
{:reply, history, state}
end

def handle_call({:data, metric}, _from, %{history: history} = state) do
local_metric = List.last(metric.name)

reply =
for {time, time_metrics} <- history,
{^local_metric, data} <- time_metrics do
%{data: %{local_metric => data}, time: time}
end

{:reply, reply, state}
end

def handle_cast(:emit_telemetry, %{history: history, current: current}) do
time = System.system_time(:second)

for {key, value} <- current do
:telemetry.execute(@historic_metrics, %{key => value})
end

{:noreply, %{history: CircularBuffer.insert(history, {time, current}), current: %{}}}
end

def handle_cast({:telemetry_metric, metric_map, _metadata, _config}, %{current: current} = state) do
updated_current =
for {key, value} <- metric_map, reduce: current do
acc -> Map.put_new(acc, key, 0) |> update_in([key], &(&1 + value))
end

{:noreply, %{state | current: updated_current}}
end
end
2 changes: 1 addition & 1 deletion mix.lock
Expand Up @@ -36,7 +36,7 @@
"phoenix": {:hex, :phoenix, "1.5.1", "95156589879dc69201d5fc0ebdbfdfc7901a09a3616ea611ec297f81340275a2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc272b38e79d2881790fccae6f67a9fbe9b790103d6878175ea03d23003152eb"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.1.0", "a044d0756d0464c5a541b4a0bf4bcaf89bffcaf92468862408290682c73ae50d", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c5e666a341ff104d0399d8f0e4ff094559b2fde13a5985d4cb5023b2c2ac558b"},
"phoenix_html": {:hex, :phoenix_html, "2.14.2", "b8a3899a72050f3f48a36430da507dd99caf0ac2d06c77529b1646964f3d563e", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "58061c8dfd25da5df1ea0ca47c972f161beb6c875cd293917045b92ffe1bf617"},
"phoenix_live_dashboard": {:git, "https://github.com/bglusman/phoenix_live_dashboard.git", "3f10c91457cf4c5e538f40086cd7ce0b318954e8", [branch: "historical_data"]},
"phoenix_live_dashboard": {:git, "https://github.com/bglusman/phoenix_live_dashboard.git", "9259f4480c8114099bda8ec5d9bda070aad06d02", [branch: "historical_data"]},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.1", "274a4b07c4adbdd7785d45a8b0bb57634d0b4f45b18d2c508b26c0344bd59b8f", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "41b4103a2fa282cfd747d377233baf213c648fdcc7928f432937676532490eee"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.12.1", "42f591c781edbf9fab921319076b7ac635d43aa23e6748d2644563326236d7e4", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.4.16 or ~> 1.5.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "585321e98df1cd5943e370b9784e950a37ca073744eb534660c9048967c52ab6"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
Expand Down

0 comments on commit 5fcb503

Please sign in to comment.