X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Ftelemetry%2Flogger.ex;h=35e245237ec5abf5004b890df5e273eddd1ac247;hb=de7f84deb3ebe57744630950860f8fbf64a414a2;hp=197b1d091679fd85884f7ec40a7a3294e5333b9e;hpb=eca8d267846afc802f9a5ceed036482a9c90b4e2;p=akkoma diff --git a/lib/pleroma/telemetry/logger.ex b/lib/pleroma/telemetry/logger.ex index 197b1d091..35e245237 100644 --- a/lib/pleroma/telemetry/logger.ex +++ b/lib/pleroma/telemetry/logger.ex @@ -1,3 +1,7 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Telemetry.Logger do @moduledoc "Transforms Pleroma telemetry events to logs" @@ -8,10 +12,16 @@ defmodule Pleroma.Telemetry.Logger do [:pleroma, :connection_pool, :reclaim, :stop], [:pleroma, :connection_pool, :provision_failure], [:pleroma, :connection_pool, :client, :dead], - [:pleroma, :connection_pool, :client, :add] + [:pleroma, :connection_pool, :client, :add], + [:pleroma, :repo, :query] ] def attach do - :telemetry.attach_many("pleroma-logger", @events, &handle_event/4, []) + :telemetry.attach_many( + "pleroma-logger", + @events, + &Pleroma.Telemetry.Logger.handle_event/4, + [] + ) end # Passing anonymous functions instead of strings to logger is intentional, @@ -25,9 +35,7 @@ defmodule Pleroma.Telemetry.Logger do _ ) do Logger.debug(fn -> - "Connection pool is exhausted (reached #{max_connections} connections). Starting idle connection cleanup to reclaim as much as #{ - reclaim_max - } connections" + "Connection pool is exhausted (reached #{max_connections} connections). Starting idle connection cleanup to reclaim as much as #{reclaim_max} connections" end) end @@ -69,9 +77,7 @@ defmodule Pleroma.Telemetry.Logger do _ ) do Logger.warn(fn -> - "Pool worker for #{key}: Client #{inspect(client_pid)} died before releasing the connection with #{ - inspect(reason) - }" + "Pool worker for #{key}: Client #{inspect(client_pid)} died before releasing the connection with #{inspect(reason)}" end) end @@ -87,4 +93,64 @@ defmodule Pleroma.Telemetry.Logger do end def handle_event([:pleroma, :connection_pool, :client, :add], _, _, _), do: :ok + + def handle_event( + [:pleroma, :repo, :query] = _name, + %{query_time: query_time} = measurements, + %{source: source} = metadata, + config + ) do + logging_config = Pleroma.Config.get([:telemetry, :slow_queries_logging], []) + + if logging_config[:enabled] && + logging_config[:min_duration] && + query_time > logging_config[:min_duration] and + (is_nil(logging_config[:exclude_sources]) or + source not in logging_config[:exclude_sources]) do + log_slow_query(measurements, metadata, config) + else + :ok + end + end + + defp log_slow_query( + %{query_time: query_time} = _measurements, + %{source: _source, query: query, params: query_params, repo: repo} = _metadata, + _config + ) do + sql_explain = + with {:ok, %{rows: explain_result_rows}} <- + repo.query("EXPLAIN " <> query, query_params, log: false) do + Enum.map_join(explain_result_rows, "\n", & &1) + end + + {:current_stacktrace, stacktrace} = Process.info(self(), :current_stacktrace) + + pleroma_stacktrace = + Enum.filter(stacktrace, fn + {__MODULE__, _, _, _} -> + false + + {mod, _, _, _} -> + mod + |> to_string() + |> String.starts_with?("Elixir.Pleroma.") + end) + + Logger.warn(fn -> + """ + Slow query! + + Total time: #{round(query_time / 1_000)} ms + + #{query} + + #{inspect(query_params, limit: :infinity)} + + #{sql_explain} + + #{Exception.format_stacktrace(pleroma_stacktrace)} + """ + end) + end end