defmodule Observer.Web.Components.Metrics.Phoenix do
@moduledoc false
use Observer.Web, :html
use Phoenix.Component
alias Observer.Web.Components.Core
attr :title, :string, required: true
attr :service, :string, required: true
attr :metric, :string, required: true
attr :metrics, :list, required: true
attr :cols, :integer, default: 1
attr :transition, :boolean, default: false
attr :supported_metrics, :list,
default: [
"phoenix.endpoint.start.system_time",
"phoenix.endpoint.stop.duration",
"phoenix.router_dispatch.start.system_time",
"phoenix.router_dispatch.exception.duration",
"phoenix.router_dispatch.stop.duration",
"phoenix.socket_connected.duration",
"phoenix.channel_joined.duration",
"phoenix.channel_handled_in.duration"
]
def content(assigns) do
~H"""
<%= cond do %>
<% @metric == "phoenix.router_dispatch.start.system_time" -> %>
<:col :let={{_timestamp, metric}} label="Collected Time">
<.timestamp timestamp={metric.timestamp} />
<:col :let={{_timestamp, metric}} label="Start">
<.timestamp timestamp={metric.value} />
<:col :let={{_timestamp, metric}} label="Method">
<.method value={metric.tags[:method]} />
<:col :let={{_timestamp, metric}} label="Route">{metric.tags[:route]}
<% @metric == "phoenix.router_dispatch.stop.duration" -> %>
<:col :let={{_timestamp, metric}} label="Collected Time">
<.timestamp timestamp={metric.timestamp} />
<:col :let={{_timestamp, metric}} label="Method">
<.method value={metric.tags[:method]} />
<:col :let={{_timestamp, metric}} label="Route">{metric.tags[:route]}
<:col :let={{_timestamp, metric}} label="Duration">
<.duration value={metric.value} unit={metric.unit} />
<:col :let={{_timestamp, metric}} label="Status">
<.html_status status={metric.tags[:status]} />
<% @metric == "phoenix.endpoint.start.system_time" -> %>
<:col :let={{_timestamp, metric}} label="Collected Time">
<.timestamp timestamp={metric.timestamp} />
<:col :let={{_timestamp, metric}} label="Start">
<.timestamp timestamp={metric.value} />
<:col :let={{_timestamp, metric}} label="Method">
<.method value={metric.tags[:method]} />
<% @metric == "phoenix.endpoint.stop.duration" -> %>
<:col :let={{_timestamp, metric}} label="Collected Time">
<.timestamp timestamp={metric.timestamp} />
<:col :let={{_timestamp, metric}} label="Method">
<.method value={metric.tags[:method]} />
<:col :let={{_timestamp, metric}} label="Duration">
<.duration value={metric.value} unit={metric.unit} />
<:col :let={{_timestamp, metric}} label="Status">
<.html_status status={metric.tags[:status]} />
<% true -> %>
<:col :let={{_timestamp, metric}} label="Collected Time">
<.timestamp timestamp={metric.timestamp} />
<:col :let={{_timestamp, metric}} label="Duration">
<.duration value={metric.value} unit={metric.unit} />
<% end %>
"""
end
defp timestamp(%{timestamp: timestamp} = assigns) when is_float(timestamp),
do: timestamp(%{assigns | timestamp: trunc(timestamp)})
defp timestamp(assigns) do
~H"""
{@timestamp |> DateTime.from_unix!(:millisecond) |> DateTime.to_string()}
"""
end
defp method(assigns) do
~H"""
{@value}
"""
end
defp duration(%{unit: unit} = assigns) do
unit =
if unit == " millisecond" do
"ms"
else
unit
end
assigns =
assigns
|> assign(unit: unit)
~H"""
{"#{:erlang.float_to_binary(@value, [{:decimals, 2}])} #{@unit}"}
"""
end
defp html_status(%{status: status} = assigns) do
color =
cond do
status >= 200 and status < 300 ->
"text-green-600"
status >= 300 and status < 400 ->
"text-yellow-600"
status >= 400 and status < 600 ->
"text-red-600"
true ->
"text-white"
end
assigns =
assigns
|> assign(color: color)
~H"""
{@status}
"""
end
end