logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

healthcheck.ex (2029B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Healthcheck do
  5. @moduledoc """
  6. Module collects metrics about app and assign healthy status.
  7. """
  8. alias Pleroma.Healthcheck
  9. alias Pleroma.Repo
  10. @derive Jason.Encoder
  11. defstruct pool_size: 0,
  12. active: 0,
  13. idle: 0,
  14. memory_used: 0,
  15. job_queue_stats: nil,
  16. healthy: true
  17. @type t :: %__MODULE__{
  18. pool_size: non_neg_integer(),
  19. active: non_neg_integer(),
  20. idle: non_neg_integer(),
  21. memory_used: number(),
  22. job_queue_stats: map(),
  23. healthy: boolean()
  24. }
  25. @spec system_info() :: t()
  26. def system_info do
  27. %Healthcheck{
  28. memory_used: Float.round(:recon_alloc.memory(:allocated) / 1024 / 1024, 2)
  29. }
  30. |> assign_db_info()
  31. |> assign_job_queue_stats()
  32. |> check_health()
  33. end
  34. defp assign_db_info(healthcheck) do
  35. database = Pleroma.Config.get([Repo, :database])
  36. query =
  37. "select state, count(pid) from pg_stat_activity where datname = '#{database}' group by state;"
  38. result = Repo.query!(query)
  39. pool_size = Pleroma.Config.get([Repo, :pool_size])
  40. db_info =
  41. Enum.reduce(result.rows, %{active: 0, idle: 0}, fn [state, cnt], states ->
  42. if state == "active" do
  43. Map.put(states, :active, states.active + cnt)
  44. else
  45. Map.put(states, :idle, states.idle + cnt)
  46. end
  47. end)
  48. |> Map.put(:pool_size, pool_size)
  49. Map.merge(healthcheck, db_info)
  50. end
  51. defp assign_job_queue_stats(healthcheck) do
  52. stats = Pleroma.JobQueueMonitor.stats()
  53. Map.put(healthcheck, :job_queue_stats, stats)
  54. end
  55. @spec check_health(Healthcheck.t()) :: Healthcheck.t()
  56. def check_health(%{pool_size: pool_size, active: active} = check)
  57. when active >= pool_size do
  58. %{check | healthy: false}
  59. end
  60. def check_health(check), do: check
  61. end