Current section

Files

Jump to
spandex_phoenix lib spandex_phoenix plug start_trace.ex
Raw

lib/spandex_phoenix/plug/start_trace.ex

defmodule SpandexPhoenix.Plug.StartTrace do
@moduledoc false
@behaviour Plug
alias Spandex.SpanContext
@init_opts Optimal.schema(
opts: [
filter_traces: {:function, 1},
span_name: :string,
tracer: :atom
],
defaults: [
filter_traces: &__MODULE__.trace_all_requests/1,
span_name: "request",
tracer: Application.get_env(:spandex_phoenix, :tracer)
],
describe: [
filter_traces: "A function that takes a Plug.Conn and returns true for requests to be traced.",
span_name: "The name to be used for the top level span.",
tracer: "The tracing module to be used to start the trace."
]
)
@doc false
def __schema__, do: @init_opts
@impl Plug
def init(opts), do: Optimal.validate!(opts, @init_opts)
@impl Plug
def call(conn, opts) do
if opts[:filter_traces].(conn) do
begin_tracing(conn, opts)
else
conn
end
end
@spec trace_all_requests(Plug.Conn.t()) :: true
@doc "Default implementation of the filter_traces function"
def trace_all_requests(_conn), do: true
# Private Helpers
defp begin_tracing(conn, opts) do
tracer = opts[:tracer]
case tracer.distributed_context(conn) do
{:ok, %SpanContext{} = span_context} ->
tracer.continue_trace(opts[:span_name], span_context)
{:error, _} ->
tracer.start_trace(opts[:span_name])
end
conn
end
end