Diagnostics tasks (#348)
a bunch of ways to get query plans to help with debugging Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk> Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/348
This commit is contained in:
parent
4f2f2c9125
commit
09326ffa56
3 changed files with 109 additions and 2 deletions
30
docs/docs/administration/CLI_tasks/diagnostics.md
Normal file
30
docs/docs/administration/CLI_tasks/diagnostics.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Diagnostics
|
||||
|
||||
A few tasks to help with debugging, troubleshooting, and diagnosing problems.
|
||||
|
||||
They mostly relate to common postgres queries.
|
||||
|
||||
## Home timeline query plan
|
||||
|
||||
This task will print a query plan for the home timeline of a given user.
|
||||
|
||||
=== "OTP"
|
||||
|
||||
`./bin/pleroma_ctl diagnostics home_timeline <nickname>`
|
||||
|
||||
=== "From Source"
|
||||
|
||||
`mix pleroma.diagnostics home_timeline <nickname>`
|
||||
|
||||
## User timeline query plan
|
||||
|
||||
This task will print a query plan for the user timeline of a given user,
|
||||
from the perspective of another given user.
|
||||
|
||||
=== "OTP"
|
||||
|
||||
`./bin/pleroma_ctl diagnostics user_timeline <nickname> <viewing_nickname>`
|
||||
|
||||
=== "From Source"
|
||||
|
||||
`mix pleroma.diagnostics user_timeline <nickname> <viewing_nickname>`
|
77
lib/mix/tasks/pleroma/diagnostics.ex
Normal file
77
lib/mix/tasks/pleroma/diagnostics.ex
Normal file
|
@ -0,0 +1,77 @@
|
|||
defmodule Mix.Tasks.Pleroma.Diagnostics do
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
|
||||
require Logger
|
||||
require Pleroma.Constants
|
||||
|
||||
import Mix.Pleroma
|
||||
import Ecto.Query
|
||||
use Mix.Task
|
||||
|
||||
def run(["home_timeline", nickname]) do
|
||||
start_pleroma()
|
||||
user = Repo.get_by!(User, nickname: nickname)
|
||||
Logger.info("Home timeline query #{user.nickname}")
|
||||
|
||||
followed_hashtags =
|
||||
user
|
||||
|> User.followed_hashtags()
|
||||
|> Enum.map(& &1.id)
|
||||
|
||||
params =
|
||||
%{limit: 20}
|
||||
|> Map.put(:type, ["Create", "Announce"])
|
||||
|> Map.put(:blocking_user, user)
|
||||
|> Map.put(:muting_user, user)
|
||||
|> Map.put(:reply_filtering_user, user)
|
||||
|> Map.put(:announce_filtering_user, user)
|
||||
|> Map.put(:user, user)
|
||||
|> Map.put(:followed_hashtags, followed_hashtags)
|
||||
|> Map.delete(:local)
|
||||
|
||||
list_memberships = Pleroma.List.memberships(user)
|
||||
recipients = [user.ap_id | User.following(user)]
|
||||
|
||||
query =
|
||||
Pleroma.Web.ActivityPub.ActivityPub.fetch_activities_query(
|
||||
recipients ++ list_memberships,
|
||||
params
|
||||
)
|
||||
|> limit(20)
|
||||
|
||||
Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
|
||||
|> IO.puts()
|
||||
end
|
||||
|
||||
def run(["user_timeline", nickname, reading_nickname]) do
|
||||
start_pleroma()
|
||||
user = Repo.get_by!(User, nickname: nickname)
|
||||
reading_user = Repo.get_by!(User, nickname: reading_nickname)
|
||||
Logger.info("User timeline query #{user.nickname}")
|
||||
|
||||
params =
|
||||
%{limit: 20}
|
||||
|> Map.put(:type, ["Create", "Announce"])
|
||||
|> Map.put(:user, reading_user)
|
||||
|> Map.put(:actor_id, user.ap_id)
|
||||
|> Map.put(:pinned_object_ids, Map.keys(user.pinned_objects))
|
||||
|
||||
list_memberships = Pleroma.List.memberships(user)
|
||||
|
||||
recipients =
|
||||
%{
|
||||
godmode: params[:godmode],
|
||||
reading_user: reading_user
|
||||
}
|
||||
|> Pleroma.Web.ActivityPub.ActivityPub.user_activities_recipients()
|
||||
|
||||
query =
|
||||
(recipients ++ list_memberships)
|
||||
|> Pleroma.Web.ActivityPub.ActivityPub.fetch_activities_query(params)
|
||||
|> limit(20)
|
||||
|
||||
Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
|
||||
|> IO.puts()
|
||||
end
|
||||
end
|
|
@ -739,9 +739,9 @@ defp fetch_activities_for_reading_user(reading_user, params) do
|
|||
|> fetch_activities(params, :offset)
|
||||
end
|
||||
|
||||
defp user_activities_recipients(%{godmode: true}), do: []
|
||||
def user_activities_recipients(%{godmode: true}), do: []
|
||||
|
||||
defp user_activities_recipients(%{reading_user: reading_user}) do
|
||||
def user_activities_recipients(%{reading_user: reading_user}) do
|
||||
if not is_nil(reading_user) and reading_user.local do
|
||||
[
|
||||
Constants.as_public(),
|
||||
|
|
Loading…
Reference in a new issue