Phoenix Integration
Instrument Elixir Phoenix applications with one Hex package. Channel tracing, LiveView lifecycle monitoring, Ecto query spans, and BEAM scheduler metrics — zero configuration.
How It Works
Add the Hex Package
Add {:tigerops, "~> 0.1"} to your mix.exs deps. The package attaches to Phoenix Telemetry events using :telemetry.attach/4 and exports spans over OTLP HTTP. It bundles opentelemetry_phoenix and opentelemetry_ecto automatically.
Add to Your Application Supervisor
Add TigerOps to your application.ex children list: {TigerOps, [service_name: "my-phoenix-app"]}. TigerOps starts its OTLP exporter process and attaches Telemetry handlers for Phoenix, LiveView, and Ecto events during supervision tree startup.
Configure via Config or Environment
Set TIGEROPS_API_KEY, TIGEROPS_SERVICE_NAME, and TIGEROPS_ENVIRONMENT. In config/runtime.exs, use System.get_env/1 to read these. The TigerOps configuration is merged at runtime so Mix releases read the correct production values.
Traces, LiveView & Ecto Query Spans
Within seconds TigerOps receives Phoenix controller spans, LiveView mount and handle_event spans, Ecto query traces with normalized SQL, and BEAM scheduler utilization metrics from your Elixir application.
What You Get Out of the Box
Phoenix Channel Tracing
Channel join, leave, and handle_in events create spans with the channel topic, event name, and payload size. Channel message routing through Phoenix PubSub is traced across nodes in clustered deployments using distributed trace propagation.
LiveView Lifecycle Monitoring
LiveView mount, handle_event, handle_info, and render phases are each measured as child spans. Slow renders are flagged with the component module name. LiveComponent update cycles are traced separately for granular performance insight.
Ecto Query Spans
Every Ecto query becomes a child span with normalized SQL, schema module name, query type (select, insert, update, delete), execution time, and row count. Ecto multi-operations create linked spans for each individual operation.
BEAM Scheduler Metrics
BEAM scheduler utilization, run queue length, process count, port count, atom table usage, and memory allocation per process type are collected via :erlang.statistics/1 and emitted as OTLP metrics every 30 seconds.
Plug & Router Instrumentation
Every Plug pipeline stage is measured as a child span. Phoenix Router dispatch, controller action dispatch, and view rendering are separately timed. Plug.Conn attributes like remote IP and request path are attached to root spans.
Oban Job Tracing
Oban job insertion and execution create linked spans. Worker module name, queue name, attempt number, and execution time are recorded. Failed jobs capture the exception and stack trace. Job queue depth is tracked as a gauge.
Install & Initialize
One Hex package. One supervisor child. Full Phoenix observability.
# mix.exs — add to deps
defp deps do
[
{:phoenix, "~> 1.7"},
{:tigerops, "~> 0.1"},
# ...
]
end
# config/runtime.exs
config :tigerops,
api_key: System.get_env("TIGEROPS_API_KEY"),
service_name: System.get_env("TIGEROPS_SERVICE_NAME", "my-phoenix-app"),
environment: System.get_env("TIGEROPS_ENVIRONMENT", "production"),
trace_ecto: true,
trace_oban: true,
trace_liveview: true
# lib/my_app/application.ex — add to children
def start(_type, _args) do
children = [
MyAppWeb.Endpoint,
{TigerOps, []}, # <-- add this
MyApp.Repo,
# ...
]
Supervisor.start_link(children, strategy: :one_for_one)
end
# Custom span in a controller action
defmodule MyAppWeb.OrderController do
use MyAppWeb, :controller
def create(conn, params) do
TigerOps.with_span("order.process", %{"order.items" => length(params["items"])},
fn ->
order = MyApp.Orders.create!(params)
json(conn, order)
end
)
end
endCommon Questions
Which Phoenix and Elixir versions are supported?
Phoenix 1.7.x is fully supported on Elixir 1.14, 1.15, and 1.16 with OTP 25 and 26. The package uses Phoenix.Telemetry events so it is compatible with both LiveView and traditional controller-based Phoenix applications.
How does TigerOps propagate trace context across Phoenix.PubSub messages?
TigerOps serializes the W3C trace context into Phoenix.PubSub message metadata when using broadcast_from/3. Subscribers reading these messages via handle_info/2 automatically restore the parent trace context if they use TigerOps.Channel.handle_info/2.
Can TigerOps trace distributed Elixir nodes connected with libcluster?
Yes. TigerOps propagates trace context through :erpc.call/4 and GenServer.call/3 using the process dictionary. Nodes must all run the tigerops package. The originating node ID is recorded as a span attribute for cross-node tracing.
Does TigerOps instrument Phoenix.Token verification calls?
Phoenix.Token.verify/4 calls within controllers and LiveView mount are traced as child spans recording the token salt (hashed), verification result (valid/invalid/expired), and verification duration. Token contents are never recorded.
How do I instrument custom GenServer processes in addition to Phoenix?
Add use TigerOps.GenServer to any GenServer module. This wraps handle_call/3, handle_cast/2, and handle_info/2 with spans named after the message pattern. The GenServer module name and process ID are recorded as span attributes.
Full Phoenix Observability in One Hex Package
Channel traces, LiveView spans, Ecto query monitoring, and BEAM metrics — no code changes required.