ElixirDashboard

Hex.pmDocumentationLicense

A Phoenix LiveView performance monitoring dashboard for tracking slow endpoints and database queries during development.

ElixirDashboard is a lightweight, zero-configuration monitoring tool that helps you identify performance bottlenecks in your Phoenix application by tracking slow HTTP endpoints and database queries in real-time.

Features

Quick Start

As a Library (Recommended)

Add to your Phoenix application in 3 simple steps:

1. Add Dependency

# mix.exs
def deps do
  [
    {:elixir_dashboard, "~> 0.2.0"}
  ]
end
mix deps.get

2. Add to Supervision Tree

# lib/my_app/application.ex
defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      MyApp.Repo,
      {Phoenix.PubSub, name: MyApp.PubSub},
      # Add ElixirDashboard
      ElixirDashboard.PerformanceMonitor.Supervisor,
      MyAppWeb.Endpoint
    ]

    # Attach telemetry handlers (development only)
    if Mix.env() == :dev do
      ElixirDashboard.PerformanceMonitor.TelemetryHandler.attach()
    end

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

3. Add Routes

# lib/my_app_web/router.ex
if Mix.env() == :dev do
  scope "/dev" do
    pipe_through :browser

    live "/performance/endpoints", ElixirDashboard.PerformanceLive.Endpoints, :index
    live "/performance/queries", ElixirDashboard.PerformanceLive.Queries, :index
  end
end

4. Configure (Optional)

# config/dev.exs
config :elixir_dashboard,
  # Application name shown in UI (default: "ElixirDashboard")
  app_name: "MyApp Dashboard",
  # Maximum items to keep in memory (default: 100)
  max_items: 100,
  # Endpoint threshold in milliseconds (default: 100)
  endpoint_threshold_ms: 100,
  # Query threshold in milliseconds (default: 50)
  query_threshold_ms: 50,
  # Auto-refresh interval in milliseconds (default: 5000)
  refresh_interval_ms: 5000,
  # Ecto repo telemetry prefixes to monitor
  repo_prefixes: [[:my_app, :repo]]

Important: Set repo_prefixes to match your Ecto repo module name.

The app_name will appear in:

That's it! Visit http://localhost:4000/dev/performance/endpoints ๐ŸŽ‰

As a Standalone App (Demo/Development)

git clone https://github.com/nshkrdotcom/elixir_dashboard.git
cd elixir_dashboard
mix deps.get
./start.sh

Visit http://localhost:4000


๐Ÿงช Testing the Dashboard (Demo Mode)

The standalone app includes a complete demo system with real slow queries and persistent DETS storage.

Quick Test - Generate Data Instantly

With the server running (./start.sh), open a new terminal and run:

# Generate 20 random slow requests (HTTP calls to demo endpoints)
mix dashboard.test 20

# Output:
# ๐Ÿš€ Generating 20 test requests to http://localhost:4000...
# ....................
# โœ“ Generated 20 test requests
#
# Refresh browser to see results:
#   http://localhost:4000/dev/performance/endpoints
#   http://localhost:4000/dev/performance/queries

Then refresh your browser - you'll immediately see slow endpoints and queries!

CLI Commands

mix dashboard.test [count]

Generates test traffic by making HTTP requests to demo endpoints.

Server must be running!

mix dashboard.test 50   # Generate 50 random slow requests

Randomly hits these endpoints:

mix dashboard.stats

View current statistics from DETS storage.

mix dashboard.stats

# Output:
# === ElixirDashboard Statistics ===
#
# Storage Type:    DETS
# Storage Path:    priv/dets
# Max Items:       100
#
# Endpoints:       47 recorded
# Queries:         89 recorded
#
# Top 5 Slowest Endpoints:
#   521ms - GET /demo/random_slow
#   203ms - GET /demo/slow_cpu?ms=150
#   ...

mix dashboard.slow_query [seconds]

Execute a single slow query directly (without HTTP).

mix dashboard.slow_query 0.2

# Output:
# ๐Ÿ˜ Executing slow query (pg_sleep 0.2s)...
# โœ“ Query completed
#   Found 1000 users in database

mix dashboard.clear

Clear all recorded data from DETS.

mix dashboard.clear

# Output:
# โœ“ Dashboard data cleared

Demo Endpoints (Click to Test)

With the server running, visit these URLs in your browser:

URL Description Expected Duration
http://localhost:4000/demo/slow_cpu?ms=200 CPU-bound delay ~200ms
http://localhost:4000/demo/slow_query?seconds=0.15 Database pg_sleep ~150ms
http://localhost:4000/demo/complex_query Complex JOIN + aggregation ~80-100ms
http://localhost:4000/demo/multiple_queries Multiple correlated queries ~200ms
http://localhost:4000/demo/random_slow Random delays 100-500ms

Persistent Storage (DETS)

Unlike in-memory storage, DETS persists data across server restarts:

# Generate some data
mix dashboard.test 10

# Restart the server
# Your data is still there! Check the dashboards.

Storage location:priv/dets/

Why You See Nothing Initially

The dashboards start empty by design because:

  1. No slow requests yet - You need to trigger endpoints that exceed the thresholds
  2. Thresholds matter - Only endpoints >100ms and queries >50ms are captured
  3. Real monitoring - This mirrors production behavior (you only see actual slow requests)

To populate the dashboard:

  1. Run mix dashboard.test 20 (easiest!)
  2. OR click the demo endpoint links on the homepage
  3. OR manually visit the /demo/* URLs
  4. Refresh the dashboard pages to see results

What You Get

Slow Endpoints Dashboard (/dev/performance/endpoints)

Track your slowest HTTP endpoints with real-time updates:

Slow Queries Dashboard (/dev/performance/queries)

Monitor database performance:

How It Works

ElixirDashboard uses Phoenix's built-in :telemetry events:

graph LR
    A[HTTP Request] --> B[Phoenix Endpoint]
    B --> C[Telemetry Event]
    C --> D[TelemetryHandler]
    D --> E[Store GenServer]
    E --> F[LiveView Dashboard]

    B --> G[Ecto Query]
    G --> H[Telemetry Event]
    H --> D
  1. Phoenix emits[:phoenix, :endpoint, :stop] events for HTTP requests
  2. Ecto emits[app, :repo, :query] events for database queries
  3. TelemetryHandler captures events above configured thresholds
  4. Store GenServer maintains top N slowest items in memory
  5. LiveView displays data with auto-refresh

Configuration

All settings are optional with sensible defaults:

Option Default Description
app_name"ElixirDashboard" Application name displayed in UI (nav, titles, headers)
max_items100 Maximum items to keep in memory per category
endpoint_threshold_ms100 Only capture endpoints slower than this (ms)
query_threshold_ms50 Only capture queries slower than this (ms)
refresh_interval_ms5000 LiveView auto-refresh interval (ms)
repo_prefixes[] List of Ecto repo telemetry prefixes

Finding Your Repo Prefix

Your Ecto repo module determines the telemetry prefix:

# If your repo is:
defmodule MyApp.Repo do
  use Ecto.Repo, otp_app: :my_app
end

# Then your prefix is:
repo_prefixes: [[:my_app, :repo]]

# For multiple repos:
repo_prefixes: [[:my_app, :repo], [:my_app, :read_repo]]

API Reference

Programmatic Access

# Get slow endpoints
endpoints = ElixirDashboard.PerformanceMonitor.get_slow_endpoints()

# Get slow queries
queries = ElixirDashboard.PerformanceMonitor.get_slow_queries()

# Clear all data
ElixirDashboard.PerformanceMonitor.clear_all()

# Runtime control
ElixirDashboard.PerformanceMonitor.attach()   # Start monitoring
ElixirDashboard.PerformanceMonitor.detach()   # Stop monitoring

Documentation

Requirements

Architecture

ElixirDashboard is designed as a dual-purpose library:

Library Mode (For Production Apps)

Standalone Mode (For Development/Demos)

See LIBRARY_USAGE.md for architectural details.

Why ElixirDashboard?

Problem: You're developing a Phoenix app and notice slow responses, but you don't want to:

Solution: ElixirDashboard gives you instant visibility into your app's performance with zero setup.

Comparison

Feature ElixirDashboard Phoenix LiveDashboard New Relic Manual Logging
Setup Time 3 minutes Included Hours Ongoing
Slow Endpoints โœ… โŒ โœ… Manual
Slow Queries โœ… โŒ โœ… Manual
Request Correlation โœ… โŒ โœ… Manual
Development-Only โœ… โŒ โŒ N/A
External Service โŒ โŒ โœ… โŒ
Zero Config โœ… โœ… โŒ N/A

Integration with New Relic

ElixirDashboard complements (not replaces) production monitoring:

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE for details.

Support

Credits

Designed as a companion tool for the New Relic Elixir Agent to provide local development insights.


Made with โค๏ธ by nshkrdotcom