While its data was included in healthcheck responses, it was not used to determine the healthy status and for informational purposes Prometheus metrics, ObanWeb dashboard or the Phoenix live dashboard are all better fits. In particular, the data shown in healtcheck responses had no temporal information, but there’s quite a difference between X failures scattered across many days of uptime and X failures within a couple minutes.
65 lines
1.7 KiB
Elixir
65 lines
1.7 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Pleroma.Healthcheck do
|
|
@moduledoc """
|
|
Module collects metrics about app and assign healthy status.
|
|
"""
|
|
alias Pleroma.Healthcheck
|
|
alias Pleroma.Repo
|
|
|
|
@derive Jason.Encoder
|
|
defstruct pool_size: 0,
|
|
active: 0,
|
|
idle: 0,
|
|
memory_used: 0,
|
|
healthy: true
|
|
|
|
@type t :: %__MODULE__{
|
|
pool_size: non_neg_integer(),
|
|
active: non_neg_integer(),
|
|
idle: non_neg_integer(),
|
|
memory_used: number(),
|
|
healthy: boolean()
|
|
}
|
|
|
|
@spec system_info() :: t()
|
|
def system_info do
|
|
%Healthcheck{
|
|
memory_used: Float.round(:recon_alloc.memory(:allocated) / 1024 / 1024, 2)
|
|
}
|
|
|> assign_db_info()
|
|
|> check_health()
|
|
end
|
|
|
|
defp assign_db_info(healthcheck) do
|
|
database = Pleroma.Config.get([Repo, :database])
|
|
|
|
query =
|
|
"select state, count(pid) from pg_stat_activity where datname = '#{database}' group by state;"
|
|
|
|
result = Repo.query!(query)
|
|
pool_size = Pleroma.Config.get([Repo, :pool_size])
|
|
|
|
db_info =
|
|
Enum.reduce(result.rows, %{active: 0, idle: 0}, fn [state, cnt], states ->
|
|
if state == "active" do
|
|
Map.put(states, :active, states.active + cnt)
|
|
else
|
|
Map.put(states, :idle, states.idle + cnt)
|
|
end
|
|
end)
|
|
|> Map.put(:pool_size, pool_size)
|
|
|
|
Map.merge(healthcheck, db_info)
|
|
end
|
|
|
|
@spec check_health(Healthcheck.t()) :: Healthcheck.t()
|
|
def check_health(%{pool_size: pool_size, active: active} = check)
|
|
when active >= pool_size do
|
|
%{check | healthy: false}
|
|
end
|
|
|
|
def check_health(check), do: check
|
|
end
|