defmodule PlausibleWeb.DebugController do use PlausibleWeb, :controller use Plausible.IngestRepo use Plausible import Ecto.Query plug(PlausibleWeb.RequireAccountPlug) plug(PlausibleWeb.SuperAdminOnlyPlug) def clickhouse(conn, params) do cluster? = Plausible.IngestRepo.clustered_table?("events_v2") on_cluster = if(cluster?, do: "ON CLUSTER '{cluster}'", else: "") # Ensure last logs are flushed IngestRepo.query("SYSTEM FLUSH LOGS #{on_cluster}") queries = from( l in from_query_log(cluster?), select: %{ query: fragment("formatQuery(?)", l.query), log_comment: l.log_comment, type: l.type, event_time: l.event_time, query_duration_ms: l.query_duration_ms, query_id: l.query_id, memory_usage: fragment("formatReadableSize(?)", l.memory_usage), read_bytes: fragment("formatReadableSize(?)", l.read_bytes), result_bytes: fragment("formatReadableSize(?)", l.result_bytes), result_rows: l.result_rows }, where: l.type > 1 and fragment("event_time > now() - toIntervalMinute(15)"), order_by: [desc: l.event_time] ) |> filter_by_params(conn, params) |> IngestRepo.all() |> Enum.map(fn data -> Jason.decode!(data.log_comment) |> Map.merge(data) |> Map.delete(:log_comment) end) conn |> render("clickhouse.html", queries: queries ) end defp from_query_log(cluster?) do case cluster? do true -> from(l in fragment("clusterAllReplicas('{cluster}', system.query_log)")) false -> from(l in fragment("system.query_log")) end end defp filter_by_params(q, _conn, %{"user_id" => user_id}), do: where(q, [l], fragment("JSONExtractInt(?, \'user_id\') = ?", l.log_comment, ^user_id)) defp filter_by_params(q, _conn, %{"site_id" => site_id}), do: where(q, [l], fragment("JSONExtractInt(?, \'site_id\') = ?", l.log_comment, ^site_id)) defp filter_by_params(q, _conn, %{"site_domain" => site_domain}), do: where( q, [l], fragment("JSONExtractString(?, \'site_domain\') = ?", l.log_comment, ^site_domain) ) defp filter_by_params(q, conn, _), do: filter_by_params(q, conn, %{"user_id" => conn.assigns.current_user.id}) end