2019-07-10 05:13:23 +00:00
|
|
|
# Pleroma: A lightweight social networking server
|
2023-01-01 11:11:47 +00:00
|
|
|
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
2019-07-10 05:13:23 +00:00
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2019-04-22 07:19:53 +00:00
|
|
|
defmodule Pleroma.Healthcheck do
|
|
|
|
@moduledoc """
|
|
|
|
Module collects metrics about app and assign healthy status.
|
|
|
|
"""
|
|
|
|
alias Pleroma.Healthcheck
|
|
|
|
alias Pleroma.Repo
|
|
|
|
|
2019-09-11 20:04:01 +00:00
|
|
|
@derive Jason.Encoder
|
2019-04-22 07:19:53 +00:00
|
|
|
defstruct pool_size: 0,
|
|
|
|
active: 0,
|
|
|
|
idle: 0,
|
|
|
|
memory_used: 0,
|
2019-09-26 11:49:57 +00:00
|
|
|
job_queue_stats: nil,
|
2019-04-22 07:19:53 +00:00
|
|
|
healthy: true
|
|
|
|
|
|
|
|
@type t :: %__MODULE__{
|
|
|
|
pool_size: non_neg_integer(),
|
|
|
|
active: non_neg_integer(),
|
|
|
|
idle: non_neg_integer(),
|
|
|
|
memory_used: number(),
|
2019-09-26 11:49:57 +00:00
|
|
|
job_queue_stats: map(),
|
2019-04-22 07:19:53 +00:00
|
|
|
healthy: boolean()
|
|
|
|
}
|
|
|
|
|
|
|
|
@spec system_info() :: t()
|
|
|
|
def system_info do
|
|
|
|
%Healthcheck{
|
2020-05-08 20:51:59 +00:00
|
|
|
memory_used: Float.round(:recon_alloc.memory(:allocated) / 1024 / 1024, 2)
|
2019-04-22 07:19:53 +00:00
|
|
|
}
|
|
|
|
|> assign_db_info()
|
2019-09-26 11:49:57 +00:00
|
|
|
|> assign_job_queue_stats()
|
2019-04-22 07:19:53 +00:00
|
|
|
|> check_health()
|
|
|
|
end
|
|
|
|
|
|
|
|
defp assign_db_info(healthcheck) do
|
2019-05-30 08:33:58 +00:00
|
|
|
database = Pleroma.Config.get([Repo, :database])
|
2019-04-22 07:19:53 +00:00
|
|
|
|
|
|
|
query =
|
|
|
|
"select state, count(pid) from pg_stat_activity where datname = '#{database}' group by state;"
|
|
|
|
|
|
|
|
result = Repo.query!(query)
|
2019-05-30 08:33:58 +00:00
|
|
|
pool_size = Pleroma.Config.get([Repo, :pool_size])
|
2019-04-22 07:19:53 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2019-09-26 11:49:57 +00:00
|
|
|
defp assign_job_queue_stats(healthcheck) do
|
|
|
|
stats = Pleroma.JobQueueMonitor.stats()
|
|
|
|
Map.put(healthcheck, :job_queue_stats, stats)
|
|
|
|
end
|
|
|
|
|
2019-04-22 07:19:53 +00:00
|
|
|
@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
|