-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds telemetry metrics to dotcom (#2039)
* trying out metrics * rearrange config * change port * this is the right url * nebulex and req stats being sent * vm stats are coming through * phoenix telemetry * docs and tests * credo * ignore files for coverage * missing docs * remove logger from helper * mix lock file
- Loading branch information
1 parent
a6f50a0
commit 401e6f9
Showing
18 changed files
with
460 additions
and
285 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
defmodule Dotcom.Telemetry do | ||
@moduledoc """ | ||
This Supervisor establishes sends vm stats to the `TelemetryMetricsSplunk` reporter. | ||
No polling occurs as these metrics are emitted regularly anyway. | ||
""" | ||
|
||
use Supervisor | ||
|
||
alias Telemetry.Metrics | ||
|
||
@doc """ | ||
Starts the supervisor. | ||
""" | ||
def start_link(arg) do | ||
Supervisor.start_link(__MODULE__, arg, name: __MODULE__) | ||
end | ||
|
||
@doc """ | ||
Initializes the supervisor. | ||
""" | ||
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] | ||
] | ||
} | ||
] | ||
|
||
Supervisor.init(children, strategy: :one_for_one) | ||
end | ||
|
||
defp metrics do | ||
[ | ||
Metrics.last_value("vm.memory.total", unit: :byte), | ||
Metrics.last_value("vm.total_run_queue_lengths.total"), | ||
Metrics.last_value("vm.total_run_queue_lengths.cpu"), | ||
Metrics.last_value("vm.system_counts.process_count") | ||
] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
defmodule DotcomWeb.Stats do | ||
@moduledoc """ | ||
This Agent attaches to telemetry events emitted by Phoenix and aggregates them. | ||
""" | ||
|
||
use Agent | ||
|
||
@doc """ | ||
Starts the Agent and attaches to `[:phoenix, :router_dispatch, :stop]` telemetry events. | ||
""" | ||
def start_link(initial_value \\ %{}) do | ||
:telemetry.attach( | ||
"phoenix-router_dispatch-stop", | ||
[:phoenix, :router_dispatch, :stop], | ||
&__MODULE__.handle_event/4, | ||
nil | ||
) | ||
|
||
Agent.start_link(fn -> initial_value end, name: __MODULE__) | ||
end | ||
|
||
@doc """ | ||
Handles telemetry events and aggregates them by path and status. | ||
""" | ||
def handle_event(_name, measurement, metadata, _config) do | ||
method = metadata.conn.method | ||
path = metadata.route | ||
status = metadata.conn.status | ||
duration = measurement[:duration] | ||
|
||
Agent.update(__MODULE__, fn state -> | ||
if Kernel.get_in(state, [method, path, status]) do | ||
Kernel.update_in(state, [method, path, status], &(&1 ++ [duration])) | ||
else | ||
Kernel.put_in(state, [Access.key(method, %{}), Access.key(path, %{}), status], [duration]) | ||
end | ||
end) | ||
end | ||
|
||
@doc """ | ||
Dispatches the aggregated stats to the `[:phoenix, :router_dispatch, :stop]` telemetry event. | ||
Resets the Agent state after dispatching the stats. | ||
""" | ||
def dispatch_stats() do | ||
Enum.each(Agent.get(__MODULE__, & &1), &dispatch_method/1) | ||
|
||
Agent.update(__MODULE__, fn _ -> %{} end) | ||
end | ||
|
||
defp dispatch_method({method, stats}) do | ||
Enum.each(stats, fn {path, statuses} -> | ||
Enum.each(statuses, fn {status, durations} -> | ||
dispatch_stat(method, path, status, durations) | ||
end) | ||
end) | ||
end | ||
|
||
defp dispatch_stat(method, path, status, durations) do | ||
count = Enum.count(durations) | ||
|
||
avg = | ||
durations | ||
|> Enum.sum() | ||
|> Kernel.div(count) | ||
|> System.convert_time_unit(:native, :millisecond) | ||
|
||
:telemetry.execute([:dotcom_web, :request], %{count: count, avg: avg}, %{ | ||
method: method, | ||
path: path, | ||
status: status | ||
}) | ||
end | ||
end |
Oops, something went wrong.