TimelessPhoenix adds persistent metrics, logs, and traces to your Phoenix app with a single dependency. Everything shows up in LiveDashboard -- no external infrastructure required.
What you get
- Metrics -- Telemetry metrics stored in TimelessMetrics (Gorilla + Zstd TSDB) that survive restarts
- Logs -- All Logger output captured and indexed in TimelessLogs (SQLite + OpenZL compressed blocks)
- Traces -- OpenTelemetry spans stored in TimelessTraces with automatic Phoenix + Bandit instrumentation
- Dashboard -- All three as LiveDashboard pages with charts, search, and historical data
Installation with Igniter (recommended)
Per the Igniter docs, the simplest way to use
mix igniter.install in an existing Phoenix app is the archive:
mix archive.install hex igniter_new
mix igniter.install timeless_phoenix
That command adds timeless_phoenix to your dependencies, fetches deps, and runs the
timeless_phoenix.install task.
If you prefer project-local Igniter instead of the archive, add this to mix.exs:
{:igniter, "~> 0.6", only: [:dev, :test], runtime: false}Then run:
mix deps.get
mix igniter.install timeless_phoenix
This automatically:
- Adds
{TimelessPhoenix, data_dir: "priv/observability"}to your supervision tree - Configures OpenTelemetry to export spans to TimelessTraces
- Adds
import TimelessPhoenix.Routerto your Phoenix router - Adds
timeless_phoenix_dashboard "/dashboard"to your browser scope - Removes the default
live_dashboardroute (avoids live_session conflict) - Updates
.formatter.exs
By default, the installer configures disk-backed metrics, logs, and traces:
mix igniter.install timeless_phoenix
If you want ephemeral logs and traces for development or CI:
mix igniter.install timeless_phoenix --storage memory
Memory mode stores logs and traces in memory only (lost on restart). Metrics are still persisted to disk.
Manual installation
If you don't want to use Igniter, add the dependency to mix.exs:
{:timeless_phoenix, "~> 1.5"}Add to your supervision tree (lib/my_app/application.ex):
children = [
# ... existing children ...
{TimelessPhoenix, data_dir: "priv/observability"}
]Add to your router (lib/my_app_web/router.ex):
import TimelessPhoenix.Router
scope "/" do
pipe_through :browser
timeless_phoenix_dashboard "/dashboard"
endIf your router has a default LiveDashboard route (typically in a dev_routes block), remove it to avoid a live_session conflict.
Verify it's working
Start your application:
mix phx.server
Open http://localhost:4000/dashboard and you'll see:
- Home -- Standard LiveDashboard with historical metrics charts
- Timeless -- Metrics TSDB dashboard with compression stats and backups
- Logs -- Searchable log viewer with level/time filtering
- Traces -- Trace/span viewer with service, kind, and status filtering
Metrics, logs, and traces start populating immediately. Metrics persist across restarts in priv/observability/metrics/, and if using disk storage, logs and traces persist in logs/ and spans/ respectively.
Generate demo traffic
To populate the dashboards with interesting data:
mix timeless_phoenix.gen_demo
This creates a GenServer that simulates HTTP requests, database queries, background jobs, cache operations, warnings, and errors every 2 seconds. See the Demo Traffic guide for details.
Interactive demo
For a hands-on walkthrough without a Phoenix app, open the demo livebook in Livebook. It starts all three engines, generates data, renders inline SVG charts, and shows compression stats interactively.
Next steps
- Configuration Reference -- all options with defaults
- Architecture -- how the three engines are orchestrated
- Dashboard -- LiveDashboard pages and customization
- Metrics -- default metrics and adding your own
- Production Deployment -- auth, data directories, proxies
- Demo Traffic -- the demo traffic generator