Skip to content

Commit

Permalink
nebulex and req stats being sent
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonyshull committed May 7, 2024
1 parent 124b992 commit 2850372
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 198 deletions.
23 changes: 1 addition & 22 deletions lib/dotcom/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ defmodule Dotcom.Application do
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
telemetry_metrics_splunk_config = Application.get_env(:dotcom, :telemetry_metrics_splunk)

Application.put_env(
:dotcom,
:allow_indexing,
Expand All @@ -31,26 +29,7 @@ defmodule Dotcom.Application do
children =
[
{Application.get_env(:dotcom, :cache, Dotcom.Cache.Multilevel), []},
{
TelemetryMetricsSplunk,
[
metrics: [
Metrics.last_value("mbta_api.request.count"),
Metrics.last_value("mbta_api.request.avg")
],
token: telemetry_metrics_splunk_config[:token],
url: telemetry_metrics_splunk_config[:url]
]
},
{MBTA.Api.Stats, %{}},
{
:telemetry_poller,
measurements: [
{MBTA.Api.Stats, :dispatch_stats, []}
],
period: :timer.seconds(5),
init_delay: :timer.seconds(5)
}
{Req.Telemetry, []}
] ++
if Application.get_env(:dotcom, :env) != :test do
[
Expand Down
44 changes: 18 additions & 26 deletions lib/dotcom/cache/telemetry.ex
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
defmodule Dotcom.Cache.Telemetry do
@moduledoc """
This supervisor establishes a connection between the telemetry_poller and our telemetry reporters.
This supervisor establishes a connection between the telemetry_poller and the `TelemetryMetricsSplunk` reporter.
Cache stats are emitted by every level of `Dotcom.Cache.Multilevel`.
We poll for them every minute.
Currently, they are passed to two reporters:
The Statsd reporter will eventually be hooked up to Splunk metrics.
For now, it does no harm to emit them even though nothing is listening.
The custom reporter logs in a format that can be picked up in Splunk logs.
Eventually, this should be removed.
"""

use Supervisor
Expand All @@ -22,27 +14,35 @@ defmodule Dotcom.Cache.Telemetry do
end

def init(_arg) do
telemetry_metrics_splunk_config = Application.get_env(:dotcom, :telemetry_metrics_splunk)

children = [
{
:telemetry_poller,
measurements: periodic_measurements(), period: 60_000, init_delay: 5_000
TelemetryMetricsSplunk,
[
metrics: metrics(),
token: telemetry_metrics_splunk_config[:token],
url: telemetry_metrics_splunk_config[:url]
]
},
{Dotcom.Cache.Telemetry.Reporter, metrics: reporter_metrics()},
{TelemetryMetricsStatsd, metrics: statsd_metrics()}
{
:telemetry_poller,
measurements: measurements(), period: :timer.seconds(60), init_delay: :timer.seconds(5)
}
]

Supervisor.init(children, strategy: :one_for_one)
end

defp reporter_metrics do
defp measurements do
[
Metrics.last_value("dotcom.cache.multilevel.l1.stats.updates"),
Metrics.last_value("dotcom.cache.multilevel.l2.stats.updates"),
Metrics.last_value("dotcom.cache.multilevel.l3.stats.updates")
{Dotcom.Cache.Multilevel.Local, :dispatch_stats, []},
{Dotcom.Cache.Multilevel.Publisher, :dispatch_stats, []},
{Dotcom.Cache.Multilevel.Redis, :dispatch_stats, []}
]
end

defp statsd_metrics do
defp metrics do
[
Metrics.last_value("dotcom.cache.multilevel.l1.stats.hits"),
Metrics.last_value("dotcom.cache.multilevel.l1.stats.misses"),
Expand All @@ -51,12 +51,4 @@ defmodule Dotcom.Cache.Telemetry do
Metrics.last_value("dotcom.cache.multilevel.l3.stats.evictions")
]
end

defp periodic_measurements do
[
{Dotcom.Cache.Multilevel.Local, :dispatch_stats, []},
{Dotcom.Cache.Multilevel.Publisher, :dispatch_stats, []},
{Dotcom.Cache.Multilevel.Redis, :dispatch_stats, []}
]
end
end
126 changes: 0 additions & 126 deletions lib/dotcom/cache/telemetry/reporter.ex

This file was deleted.

Empty file added lib/dotcom/stats.ex
Empty file.
Empty file added lib/dotcom/telemetry.ex
Empty file.
Empty file added lib/dotcom_web/stats.ex
Empty file.
Empty file added lib/dotcom_web/telemetry.ex
Empty file.
File renamed without changes.
43 changes: 20 additions & 23 deletions lib/mbta/api/stats.ex → lib/req/stats.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule MBTA.Api.Stats do
defmodule Req.Stats do
@moduledoc """
This Agent attaches to telemetry events emitted by Finch and aggregates them by path and status.
"""
Expand All @@ -18,37 +18,40 @@ defmodule MBTA.Api.Stats do
Handles telemetry events and aggregates them by path and status.
"""
def handle_event(_name, measurement, metadata, _config) do
path = path_to_atom(metadata.request.path)
status = status_to_atom(metadata.status)
host = metadata.request.host
path = strip_filename(metadata.request.path)
status = metadata.status
duration = measurement[:duration]

Agent.update(__MODULE__, fn state ->
if Kernel.get_in(state, [path, status]) do
Kernel.update_in(state, [path, status], &(&1 ++ [duration]))
if Kernel.get_in(state, [host, path, status]) do
Kernel.update_in(state, [host, path, status], &(&1 ++ [duration]))
else
Kernel.put_in(state, [Access.key(path, %{}), status], [duration])
Kernel.put_in(state, [Access.key(host, %{}), Access.key(path, %{}), status], [duration])
end
end)
end

@doc """
Dispatches the aggregated stats to the `[:mbta_api, :request]` telemetry event.
Dispatches the aggregated stats to the `[:req, :request]` telemetry event.
Resets the Agent state after dispatching the stats.
"""
def dispatch_stats() do
Enum.each(Agent.get(__MODULE__, & &1), &dispatch_path/1)
Enum.each(Agent.get(__MODULE__, & &1), &dispatch_host/1)

Agent.update(__MODULE__, fn _ -> %{} end)
end

defp dispatch_path({path, stats}) do
Enum.each(stats, fn {status, durations} ->
dispatch_stat(path, status, durations)
defp dispatch_host({host, stats}) do
Enum.each(stats, fn {path, statuses} ->
Enum.each(statuses, fn {status, durations} ->
dispatch_stat(host, path, status, durations)
end)
end)
end

defp dispatch_stat(path, status, durations) do
defp dispatch_stat(host, path, status, durations) do
count = Enum.count(durations)

avg =
Expand All @@ -57,22 +60,16 @@ defmodule MBTA.Api.Stats do
|> Kernel.div(count)
|> System.convert_time_unit(:native, :millisecond)

:telemetry.execute([:mbta_api, :request], %{count: count, avg: avg}, %{
:telemetry.execute([:req, :request], %{count: count, avg: avg}, %{
host: host,
path: path,
status: status
})
end

defp path_to_atom(path) do
defp strip_filename(path) do
path
|> String.replace(~r{^/|/$}, "")
|> String.replace(~r{/}, "_")
|> String.to_atom()
end

defp status_to_atom(status) do
status
|> Integer.to_string()
|> String.to_atom()
|> (&Regex.replace(~r/\/$/, &1, "")).()
|> (&Regex.replace(~r/[\w|-]+\.\w+/, &1, "")).()
end
end
47 changes: 47 additions & 0 deletions lib/req/telemetry.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
defmodule Req.Telemetry do
@moduledoc """
"""

use Supervisor

alias Telemetry.Metrics

def start_link(arg) do
Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
end

def init(_arg) do
telemetry_metrics_splunk_config = Application.get_env(:dotcom, :telemetry_metrics_splunk)

children = [
{
TelemetryMetricsSplunk,
[
metrics: metrics(),
token: telemetry_metrics_splunk_config[:token],
url: telemetry_metrics_splunk_config[:url]
]
},
{
:telemetry_poller,
measurements: measurements(), period: :timer.seconds(60), init_delay: :timer.seconds(5)
},
{Req.Stats, %{}}
]

Supervisor.init(children, strategy: :one_for_one)
end

defp measurements do
[
{Req.Stats, :dispatch_stats, []}
]
end

defp metrics do
[
Metrics.last_value("req.request.count"),
Metrics.last_value("req.request.avg")
]
end
end
1 change: 0 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ defmodule DotCom.Mixfile do
{:telemetry, "1.2.1", override: true},
{:telemetry_metrics, "1.0.0", override: true},
{:telemetry_metrics_splunk, "0.0.1-alpha"},
{:telemetry_metrics_statsd, "0.7.0"},
{:telemetry_poller, "1.1.0"},
{:telemetry_test, "0.1.2", only: [:test]},
# latest version is 3.7.11; cannot upgrade because tests fail
Expand Down

0 comments on commit 2850372

Please sign in to comment.