Reduce cyclomatic complexity in aprs_symbol and database_metrics
Simplify complex functions: - aprs_symbol.ex: Simplify get_overlay_base_table_id (all cases return "1") - database_metrics.ex: Extract metric reporting helpers to reduce nesting Co-Authored-By: Graham <noreply@anthropic.com>
This commit is contained in:
parent
d48a3a291f
commit
0b5b50a13b
2 changed files with 90 additions and 133 deletions
|
|
@ -5,123 +5,99 @@ defmodule Aprsme.Telemetry.DatabaseMetrics do
|
|||
require Logger
|
||||
|
||||
def collect_db_pool_metrics do
|
||||
# Get pool configuration
|
||||
pool_size = Application.get_env(:aprsme, Aprsme.Repo)[:pool_size] || 10
|
||||
|
||||
# Try to get pool metrics using Ecto's telemetry
|
||||
# First, let's check if the repo is started
|
||||
case Process.whereis(Aprsme.Repo) do
|
||||
nil ->
|
||||
# Repo not started, report zeros
|
||||
:telemetry.execute(
|
||||
[:aprsme, :repo, :pool],
|
||||
%{
|
||||
size: pool_size,
|
||||
idle: 0,
|
||||
busy: 0,
|
||||
available: 0,
|
||||
queue_length: 0,
|
||||
total: 0
|
||||
},
|
||||
%{}
|
||||
)
|
||||
|
||||
repo_pid when is_pid(repo_pid) ->
|
||||
# Get the pool metrics from DBConnection
|
||||
# The pool supervisor is typically a child of the repo
|
||||
case Supervisor.which_children(repo_pid) do
|
||||
children when is_list(children) ->
|
||||
# Find the DBConnection child
|
||||
pool_info =
|
||||
Enum.find(children, fn
|
||||
{DBConnection.ConnectionPool, _, _, _} -> true
|
||||
# In test mode
|
||||
{DBConnection.Ownership, _, _, _} -> true
|
||||
_ -> false
|
||||
end)
|
||||
|
||||
case pool_info do
|
||||
{_, pool_pid, _, _} when is_pid(pool_pid) ->
|
||||
# Try to get pool telemetry
|
||||
pool_telemetry =
|
||||
try do
|
||||
# DBConnection exposes pool metrics via telemetry
|
||||
{:ok,
|
||||
%{
|
||||
pool_size: pool_size,
|
||||
idle_time: 0,
|
||||
queue_time: 0
|
||||
}}
|
||||
catch
|
||||
_, _ -> {:error, :not_available}
|
||||
end
|
||||
|
||||
case pool_telemetry do
|
||||
{:ok, _metrics} ->
|
||||
:telemetry.execute(
|
||||
[:aprsme, :repo, :pool],
|
||||
%{
|
||||
size: pool_size,
|
||||
# Estimate
|
||||
idle: max(0, pool_size - 2),
|
||||
# Estimate
|
||||
busy: 2,
|
||||
available: max(0, pool_size - 2),
|
||||
queue_length: 0,
|
||||
total: pool_size
|
||||
},
|
||||
%{}
|
||||
)
|
||||
|
||||
_ ->
|
||||
# Use defaults
|
||||
:telemetry.execute(
|
||||
[:aprsme, :repo, :pool],
|
||||
%{
|
||||
size: pool_size,
|
||||
idle: pool_size,
|
||||
busy: 0,
|
||||
available: pool_size,
|
||||
queue_length: 0,
|
||||
total: pool_size
|
||||
},
|
||||
%{}
|
||||
)
|
||||
end
|
||||
|
||||
_ ->
|
||||
# Pool not found, use defaults
|
||||
:telemetry.execute(
|
||||
[:aprsme, :repo, :pool],
|
||||
%{
|
||||
size: pool_size,
|
||||
idle: pool_size,
|
||||
busy: 0,
|
||||
available: pool_size,
|
||||
queue_length: 0,
|
||||
total: pool_size
|
||||
},
|
||||
%{}
|
||||
)
|
||||
end
|
||||
end
|
||||
nil -> report_pool_metrics_unavailable(pool_size)
|
||||
repo_pid when is_pid(repo_pid) -> collect_from_repo(repo_pid, pool_size)
|
||||
end
|
||||
rescue
|
||||
e ->
|
||||
Logger.debug("Error collecting pool metrics: #{inspect(e)}")
|
||||
# Emit zero metrics on error
|
||||
:telemetry.execute(
|
||||
[:aprsme, :repo, :pool],
|
||||
%{
|
||||
size: 0,
|
||||
idle: 0,
|
||||
busy: 0,
|
||||
available: 0,
|
||||
queue_length: 0,
|
||||
total: 0
|
||||
},
|
||||
%{}
|
||||
)
|
||||
report_pool_metrics_error()
|
||||
end
|
||||
|
||||
defp collect_from_repo(repo_pid, pool_size) do
|
||||
case Supervisor.which_children(repo_pid) do
|
||||
children when is_list(children) ->
|
||||
pool_info = find_pool_child(children)
|
||||
collect_from_pool(pool_info, pool_size)
|
||||
|
||||
_ ->
|
||||
report_pool_metrics_idle(pool_size)
|
||||
end
|
||||
end
|
||||
|
||||
defp find_pool_child(children) do
|
||||
Enum.find(children, fn
|
||||
{DBConnection.ConnectionPool, _, _, _} -> true
|
||||
{DBConnection.Ownership, _, _, _} -> true
|
||||
_ -> false
|
||||
end)
|
||||
end
|
||||
|
||||
defp collect_from_pool({_, pool_pid, _, _}, pool_size) when is_pid(pool_pid) do
|
||||
# Try to get pool telemetry
|
||||
case try_get_pool_telemetry(pool_size) do
|
||||
{:ok, _metrics} -> report_pool_metrics_estimated(pool_size)
|
||||
_ -> report_pool_metrics_idle(pool_size)
|
||||
end
|
||||
end
|
||||
|
||||
defp collect_from_pool(_, pool_size), do: report_pool_metrics_idle(pool_size)
|
||||
|
||||
defp try_get_pool_telemetry(pool_size) do
|
||||
{:ok, %{pool_size: pool_size, idle_time: 0, queue_time: 0}}
|
||||
catch
|
||||
_, _ -> {:error, :not_available}
|
||||
end
|
||||
|
||||
defp report_pool_metrics_unavailable(pool_size) do
|
||||
emit_pool_metrics(%{
|
||||
size: pool_size,
|
||||
idle: 0,
|
||||
busy: 0,
|
||||
available: 0,
|
||||
queue_length: 0,
|
||||
total: 0
|
||||
})
|
||||
end
|
||||
|
||||
defp report_pool_metrics_idle(pool_size) do
|
||||
emit_pool_metrics(%{
|
||||
size: pool_size,
|
||||
idle: pool_size,
|
||||
busy: 0,
|
||||
available: pool_size,
|
||||
queue_length: 0,
|
||||
total: pool_size
|
||||
})
|
||||
end
|
||||
|
||||
defp report_pool_metrics_estimated(pool_size) do
|
||||
emit_pool_metrics(%{
|
||||
size: pool_size,
|
||||
idle: max(0, pool_size - 2),
|
||||
busy: 2,
|
||||
available: max(0, pool_size - 2),
|
||||
queue_length: 0,
|
||||
total: pool_size
|
||||
})
|
||||
end
|
||||
|
||||
defp report_pool_metrics_error do
|
||||
emit_pool_metrics(%{
|
||||
size: 0,
|
||||
idle: 0,
|
||||
busy: 0,
|
||||
available: 0,
|
||||
queue_length: 0,
|
||||
total: 0
|
||||
})
|
||||
end
|
||||
|
||||
defp emit_pool_metrics(metrics) do
|
||||
:telemetry.execute([:aprsme, :repo, :pool], metrics, %{})
|
||||
end
|
||||
|
||||
def collect_postgres_metrics do
|
||||
|
|
|
|||
|
|
@ -112,29 +112,10 @@ defmodule AprsmeWeb.AprsSymbol do
|
|||
Some symbols are in the alternate table (1), others in overlay table (2).
|
||||
"""
|
||||
@spec get_overlay_base_table_id(String.t()) :: String.t()
|
||||
def get_overlay_base_table_id(base_symbol_code) do
|
||||
# Map symbols to the correct sprite table based on APRS specification
|
||||
# Most overlay symbols are in the alternate table (1)
|
||||
case base_symbol_code do
|
||||
# Digipeater symbols are often in the alternate table (1) and have colored backgrounds
|
||||
# Digipeater - green star background
|
||||
"#" -> "1"
|
||||
# Diamond shape - APRS overlay symbol (alternate table)
|
||||
"a" -> "1"
|
||||
# Square shape - APRS overlay symbol (alternate table)
|
||||
"A" -> "1"
|
||||
# Diamond shape - alternate table
|
||||
"&" -> "1"
|
||||
# Arrow symbols
|
||||
">" -> "1"
|
||||
"<" -> "1"
|
||||
"^" -> "1"
|
||||
"v" -> "1"
|
||||
# Black square background - alternate table
|
||||
"i" -> "1"
|
||||
# Most other symbols that can be overlaid are in the alternate table
|
||||
_ -> "1"
|
||||
end
|
||||
def get_overlay_base_table_id(_base_symbol_code) do
|
||||
# All overlay symbols are in the alternate table (1) per APRS specification
|
||||
# This includes digipeaters, diamonds, squares, arrows, etc.
|
||||
"1"
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue