Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

License

Notifications You must be signed in to change notification settings

nshkrdotcom/elixir_dashboard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

18 Commits

Repository files navigation

ElixirDashboard

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

  • Zero Configuration - Works out of the box with sensible defaults
  • Real-time Monitoring - LiveView dashboards with auto-refresh
  • Dual Purpose - Use as a library in your app OR run standalone
  • Request Correlation - See which endpoints triggered slow queries
  • Color-coded Metrics - Visual performance indicators
  • Lightweight - Minimal dependencies, persistent DETS storage
  • Development-Only - Automatically disabled in production
  • Fully Configurable - Customize thresholds, limits, and intervals
  • ElixirTracer Integration - Comprehensive observability with transactions, spans, errors, metrics, and events

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:

  • Page titles (browser tab)
  • Navigation bar
  • Dashboard headers

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:

  • /demo/slow_cpu?ms=150 - CPU delay (Process.sleep)
  • /demo/slow_query?seconds=0.1 - Database delay (pg_sleep)
  • /demo/complex_query - Complex JOIN with aggregation
  • /demo/multiple_queries - Multiple correlated queries
  • /demo/random_slow - Random delays

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/

  • endpoints.dets - Slow endpoint data
  • queries.dets - Slow query data

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:

  • Duration in milliseconds
  • HTTP method and path
  • NEW with ElixirTracer: Transaction status, error count, trace IDs, custom attributes
  • Timestamp
  • Color-coded severity (green - yellow - orange - red)
  • Auto-refresh every 5 seconds
  • One-click data clearing

Slow Queries Dashboard (/dev/performance/queries)

Monitor database performance:

  • Query duration
  • Full SQL text
  • Query parameters
  • NEW with ElixirTracer: DB operation type, table name, database instance, span IDs
  • Originating endpoint (request correlation)
  • Timestamp
  • Color-coded severity

NEW: Errors Dashboard (/dev/performance/errors)

Track all exceptions with full context:

  • Error type and message
  • Full stack traces
  • Transaction correlation
  • Custom attributes
  • Statistics and frequency analysis

NEW: Metrics Dashboard (/dev/performance/metrics)

View aggregated performance data:

  • Database metrics by table/operation
  • External service call statistics
  • Custom application metrics
  • Call counts, min/max/avg durations
  • Filterable by category

NEW: Custom Events Dashboard (/dev/performance/events)

Monitor business events:

  • User signups, purchases, feature usage
  • Custom application events
  • Event attributes and payloads
  • Time-based statistics

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
Loading
  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_items 100 Maximum items to keep in memory per category
endpoint_threshold_ms 100 Only capture endpoints slower than this (ms)
query_threshold_ms 50 Only capture queries slower than this (ms)
refresh_interval_ms 5000 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

  • Elixir ~> 1.14
  • Phoenix ~> 1.7
  • Phoenix LiveView ~> 0.20

Architecture

ElixirDashboard is designed as a dual-purpose library:

Library Mode (For Production Apps)

  • Minimal core dependencies (Phoenix, LiveView, Telemetry)
  • Clean module namespace (ElixirDashboard.*)
  • No demo app overhead
  • Publishable to Hex

Standalone Mode (For Development/Demos)

  • Full Phoenix application
  • Demo routes and UI
  • Uses library code internally
  • Perfect for testing features

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:

  • Set up New Relic/external monitoring for local dev
  • Add heavyweight profiling tools
  • Manually add logging to find slow spots
  • Run separate monitoring infrastructure

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:

  • Uses the same telemetry events
  • Does not interfere with New Relic data collection
  • Provides immediate local feedback during development
  • Works independently - no New Relic configuration required

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