Skip to content

Commit 31f8c71

Browse files
cnkkzoldar
andauthored
OpenTelemetry improvements (#6007)
* include trace_id in log comments * site team_id to OpenTelemetry attributes * Move tracing to QueryRunner so that all queries profit from additional attributes in their spans * Add trace_id assertion to debug metadata test * Fix warning * add trace_id * remove integer check * log trace_id to correlate logs and traces * Update lib/plausible/clickhouse_repo.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible/open_telemetry/logger.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * mix format * Refactor trace_id retrieval --------- Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
1 parent 36d3a65 commit 31f8c71

File tree

9 files changed

+72
-7
lines changed

9 files changed

+72
-7
lines changed

config/runtime.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ log_level =
2727
|> String.to_existing_atom()
2828

2929
config :logger, level: log_level
30-
config :logger, :default_formatter, metadata: [:request_id]
30+
config :logger, :default_formatter, metadata: [:request_id, :trace_id]
3131

3232
config :logger, Sentry.LoggerBackend,
3333
capture_log_messages: true,

lib/plausible/application.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ defmodule Plausible.Application do
371371
OpentelemetryEcto.setup([:plausible, :repo])
372372
OpentelemetryEcto.setup([:plausible, :clickhouse_repo])
373373
OpentelemetryOban.setup()
374+
Plausible.OpenTelemetry.Logger.setup()
374375
end
375376

376377
defp setup_geolocation do

lib/plausible/clickhouse_repo.ex

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,17 @@ defmodule Plausible.ClickhouseRepo do
4646
@impl true
4747
def prepare_query(_operation, query, opts) do
4848
{plausible_query, opts} = Keyword.pop(opts, :query)
49-
log_comment = if(plausible_query, do: Jason.encode!(plausible_query.debug_metadata), else: "")
49+
50+
trace_id = Plausible.OpenTelemetry.current_trace_id()
51+
52+
log_comment_data =
53+
if plausible_query do
54+
Map.put(plausible_query.debug_metadata, :trace_id, trace_id)
55+
else
56+
%{trace_id: trace_id}
57+
end
58+
59+
log_comment = Jason.encode!(log_comment_data)
5060

5161
opts =
5262
Keyword.update(opts, :settings, [log_comment: log_comment], fn settings ->

lib/plausible/open_telemetry.ex

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,26 @@ defmodule Plausible.OpenTelemetry do
33

44
require OpenTelemetry.Tracer, as: Tracer
55

6+
def current_trace_id do
7+
case OpenTelemetry.Tracer.current_span_ctx() do
8+
:undefined ->
9+
nil
10+
11+
span_ctx ->
12+
span_ctx
13+
|> OpenTelemetry.Span.trace_id()
14+
|> Integer.to_string(16)
15+
|> String.downcase()
16+
end
17+
end
18+
619
def add_site_attributes(site) do
720
case site do
821
%Plausible.Site{} = site ->
922
Tracer.set_attributes([
1023
{"plausible.site.id", site.id},
11-
{"plausible.site.domain", site.domain}
24+
{"plausible.site.domain", site.domain},
25+
{"plausible.site.team_id", site.team_id}
1226
])
1327

1428
id when is_integer(id) ->
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
defmodule Plausible.OpenTelemetry.Logger do
2+
@moduledoc """
3+
Telemetry handler that adds the OpenTelemetry trace_id to Logger metadata.
4+
5+
This enables correlation between log lines and distributed traces.
6+
The trace_id is extracted from the current OTel span context and added
7+
to the Logger metadata when Phoenix router dispatch starts.
8+
"""
9+
10+
require Logger
11+
12+
@doc """
13+
Attaches telemetry handlers to set trace_id in Logger metadata.
14+
15+
Should be called during application startup, after OpentelemetryPhoenix.setup().
16+
"""
17+
def setup do
18+
:telemetry.attach(
19+
"plausible-otel-logger-metadata",
20+
[:phoenix, :router_dispatch, :start],
21+
&__MODULE__.handle_router_dispatch_start/4,
22+
%{}
23+
)
24+
end
25+
26+
@doc false
27+
def handle_router_dispatch_start(_event, _measurements, _metadata, _config) do
28+
case Plausible.OpenTelemetry.current_trace_id() do
29+
nil ->
30+
:ok
31+
32+
trace_id_hex ->
33+
Logger.metadata(trace_id: trace_id_hex)
34+
end
35+
end
36+
end

lib/plausible/stats/aggregate.ex

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ defmodule Plausible.Stats.Aggregate do
99
alias Plausible.Stats.{Query, QueryRunner, QueryResult, QueryOptimizer}
1010

1111
def aggregate(site, query, metrics) do
12-
Query.trace(query, metrics)
13-
1412
query =
1513
query
1614
|> Query.set(metrics: metrics, remove_unavailable_revenue_metrics: true)

lib/plausible/stats/query_runner.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ defmodule Plausible.Stats.QueryRunner do
1515
alias Plausible.Stats.{
1616
Comparisons,
1717
Compare,
18+
Query,
1819
QueryOptimizer,
1920
QueryResult,
2021
Metrics,
@@ -36,6 +37,8 @@ defmodule Plausible.Stats.QueryRunner do
3637
def run(site, query) do
3738
optimized_query = QueryOptimizer.optimize(query)
3839

40+
Query.trace(optimized_query, optimized_query.metrics)
41+
3942
%__MODULE__{main_query: optimized_query, site: site}
4043
|> execute_main_query()
4144
|> add_comparison_query()

test/plausible_web/controllers/api/external_stats_controller/debug_metadata_test.exs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ defmodule PlausibleWeb.Api.ExternalController.DebugMetadataTest do
1616
}
1717

1818
conn =
19-
post(conn, "api/v2/query", query)
19+
post(conn, "/api/v2/query", query)
2020

2121
assert json_response(conn, 200)
2222

@@ -38,10 +38,11 @@ defmodule PlausibleWeb.Api.ExternalController.DebugMetadataTest do
3838
"phoenix_controller" =>
3939
"Elixir.PlausibleWeb.Api.ExternalQueryApiController",
4040
"request_method" => "POST",
41-
"request_path" => "api/v2/query",
41+
"request_path" => "/api/v2/query",
4242
"site_domain" => ^site.domain,
4343
"site_id" => ^site.id,
4444
"team_id" => ^team_of(user).id,
45+
"trace_id" => _,
4546
"user_id" => ^user.id
4647
}) = decoded
4748

test/plausible_web/controllers/api/stats_controller/debug_metadata_test.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ defmodule PlausibleWeb.Api.StatsController.DebugMetadataTest do
3232
"site_domain" => ^site.domain,
3333
"site_id" => ^site.id,
3434
"team_id" => ^team_of(user).id,
35+
"trace_id" => _,
3536
"user_id" => ^user.id
3637
}) = decoded
3738
end
@@ -90,6 +91,7 @@ defmodule PlausibleWeb.Api.StatsController.DebugMetadataTest do
9091
"site_id" => ^site.id,
9192
# nil team_id because viewing a public/shared dashboard
9293
"team_id" => nil,
94+
"trace_id" => _,
9395
# the logged in user ID is included even when viewing a random public dashboard
9496
"user_id" => ^user.id
9597
}) = decoded

0 commit comments

Comments
 (0)