| 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: "") |
|
|
| |
| 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 |
|
|