Skip to content

Commit 6c329a1

Browse files
committed
Add team ID to debug metadata
1 parent 997546f commit 6c329a1

File tree

4 files changed

+162
-1
lines changed

4 files changed

+162
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
66

77
### Added
88

9+
- Adds team_id to query debug metadata (saved in system.query_log log_comment column)
910
- A visitor percentage breakdown is now shown on all reports, both on the dashboard and in the detailed breakdown
1011
- Shared links can now be limited to a particular segment of the data
1112

lib/plausible_web/controllers/helpers.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ defmodule PlausibleWeb.ControllerHelpers do
2828
phoenix_action: conn.private.phoenix_action |> to_string(),
2929
site_id: conn.assigns.site.id,
3030
site_domain: conn.assigns.site.domain,
31-
user_id: get_user_id(conn, conn.assigns)
31+
user_id: get_user_id(conn, conn.assigns),
32+
team_id: get_team_id(conn, conn.assigns)
3233
}
3334
end
3435

@@ -40,4 +41,9 @@ defmodule PlausibleWeb.ControllerHelpers do
4041
_ -> nil
4142
end
4243
end
44+
45+
defp get_team_id(_conn, %{current_team: %Plausible.Teams.Team{id: id}}), do: id
46+
defp get_team_id(_conn, %{site_team: %Plausible.Teams.Team{id: id}}), do: id
47+
defp get_team_id(_conn, %{api_context: :site, site: %Plausible.Site{team_id: id}}), do: id
48+
defp get_team_id(_conn, _assigns), do: nil
4349
end
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
defmodule PlausibleWeb.Api.ExternalController.DebugMetadataTest do
2+
alias Plausible.{IngestRepo, ClickhouseRepo}
3+
use PlausibleWeb.ConnCase, async: true
4+
5+
describe "Debug metadata" do
6+
setup [:create_user, :create_api_key, :use_api_key]
7+
8+
test "is saved correctly", %{conn: conn, user: user} do
9+
domain = :rand.bytes(20) |> Base.url_encode64()
10+
site = new_site(domain: domain, owner: user)
11+
12+
query = %{
13+
"site_id" => site.domain,
14+
"date_range" => "all",
15+
"metrics" => ["visitors"]
16+
}
17+
18+
conn =
19+
post(conn, "api/v2/query", query)
20+
21+
assert json_response(conn, 200)
22+
23+
IngestRepo.query!("SYSTEM FLUSH LOGS")
24+
25+
%{rows: [r1, r2]} =
26+
ClickhouseRepo.query!(
27+
"FROM system.query_log SELECT log_comment WHERE JSONExtractString(log_comment, 'site_domain') = {$0:String}",
28+
[site.domain]
29+
)
30+
31+
for [unparsed_log_comment] <- [r1, r2] do
32+
decoded = Jason.decode!(unparsed_log_comment)
33+
34+
assert_matches ^strict_map(%{
35+
# params are asserted below
36+
"params" => %{},
37+
"phoenix_action" => "query",
38+
"phoenix_controller" =>
39+
"Elixir.PlausibleWeb.Api.ExternalQueryApiController",
40+
"request_method" => "POST",
41+
"request_path" => "api/v2/query",
42+
"site_domain" => ^site.domain,
43+
"site_id" => ^site.id,
44+
"team_id" => ^team_of(user).id,
45+
"user_id" => ^user.id
46+
}) = decoded
47+
48+
assert decoded["params"] == query
49+
end
50+
end
51+
end
52+
end
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
defmodule PlausibleWeb.Api.StatsController.DebugMetadataTest do
2+
alias Plausible.{IngestRepo, ClickhouseRepo}
3+
use PlausibleWeb.ConnCase, async: true
4+
5+
describe "Debug metadata for logged in requests" do
6+
setup [:create_user, :log_in]
7+
8+
test "for main-graph", %{conn: conn, user: user} do
9+
domain = :rand.bytes(20) |> Base.url_encode64()
10+
site = new_site(domain: domain, owner: user)
11+
conn = get(conn, "/api/stats/#{site.domain}/main-graph")
12+
13+
assert json_response(conn, 200)
14+
15+
IngestRepo.query!("SYSTEM FLUSH LOGS")
16+
17+
%{rows: [r1, r2]} =
18+
ClickhouseRepo.query!(
19+
"FROM system.query_log SELECT log_comment WHERE JSONExtractString(log_comment, 'site_domain') = {$0:String}",
20+
[site.domain]
21+
)
22+
23+
for [unparsed_log_comment] <- [r1, r2] do
24+
decoded = Jason.decode!(unparsed_log_comment)
25+
26+
assert_matches ^strict_map(%{
27+
"params" => ^strict_map(%{"domain" => ^site.domain}),
28+
"phoenix_action" => "main_graph",
29+
"phoenix_controller" => "Elixir.PlausibleWeb.Api.StatsController",
30+
"request_method" => "GET",
31+
"request_path" => ^"/api/stats/#{site.domain}/main-graph",
32+
"site_domain" => ^site.domain,
33+
"site_id" => ^site.id,
34+
"team_id" => ^team_of(user).id,
35+
"user_id" => ^user.id
36+
}) = decoded
37+
end
38+
end
39+
end
40+
41+
defp setup_dashboard_case(domain, type) do
42+
site_owner = new_user()
43+
44+
case type do
45+
"public" ->
46+
site = new_site(domain: domain, owner: site_owner, public: true)
47+
{site, "", %{"domain" => domain}}
48+
49+
"shared" ->
50+
site = new_site(domain: domain, owner: site_owner)
51+
link = insert(:shared_link, site: site)
52+
53+
{site, "?auth=#{link.slug}", %{"domain" => domain, "auth" => link.slug}}
54+
end
55+
end
56+
57+
describe "Debug metadata for non-private dashboard requests" do
58+
setup [:create_user, :log_in]
59+
60+
for type <- ["public", "shared"] do
61+
test "for /pages request (#{type})", %{
62+
conn: conn,
63+
user: user
64+
} do
65+
domain = :rand.bytes(20) |> Base.url_encode64()
66+
{site, query_string, expected_params} = setup_dashboard_case(domain, unquote(type))
67+
conn = get(conn, "/api/stats/#{site.domain}/pages#{query_string}")
68+
69+
assert json_response(conn, 200)
70+
71+
IngestRepo.query!("SYSTEM FLUSH LOGS")
72+
73+
%{rows: [r1, r2]} =
74+
ClickhouseRepo.query!(
75+
"FROM system.query_log SELECT log_comment WHERE JSONExtractString(log_comment, 'site_domain') = {$0:String}",
76+
[site.domain]
77+
)
78+
79+
for [unparsed_log_comment] <- [r1, r2] do
80+
decoded = Jason.decode!(unparsed_log_comment)
81+
82+
assert_matches ^strict_map(%{
83+
# params are asserted below
84+
"params" => %{},
85+
"phoenix_action" => "pages",
86+
"phoenix_controller" => "Elixir.PlausibleWeb.Api.StatsController",
87+
"request_method" => "GET",
88+
"request_path" => ^"/api/stats/#{site.domain}/pages",
89+
"site_domain" => ^site.domain,
90+
"site_id" => ^site.id,
91+
# nil team_id because viewing a public/shared dashboard
92+
"team_id" => nil,
93+
# the logged in user ID is included even when viewing a random public dashboard
94+
"user_id" => ^user.id
95+
}) = decoded
96+
97+
assert decoded["params"] == expected_params
98+
end
99+
end
100+
end
101+
end
102+
end

0 commit comments

Comments
 (0)