Monitorex

CI

Real-time HTTP telemetry dashboard for Elixir/Phoenix applications.

Monitorex monitors outbound (Tesla, Finch/Req) and inbound (Phoenix) HTTP traffic, aggregates it into ETS-backed metrics, and renders a live-updating dark-theme dashboard — no database required.

Outbound Overview

Features

Installation

Add monitorex to your mix.exs:

def deps do
  [
    {:monitorex, "~> 0.3.0"}
  ]
end

Then run:

mix deps.get

Quick Start

1. Configure sources

In config/config.exs:

config :monitorex, :sources, [:tesla, :finch, :phoenix]

2. Mount the dashboard in your router

# lib/my_app_web/router.ex
defmodule MyAppWeb.Router do
  use Phoenix.Router
  import Monitorex.Router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, html: {MyAppWeb.Layouts, :root}
    plug :protect_from_forgery
  end

  scope "/monitoring" do
    pipe_through :browser
    http_dashboard []
  end
end

3. Start your server

mix phx.server

Visit /monitoring to see your dashboard.

Configuration

Sources

config :monitorex, :sources, [:tesla, :finch, :phoenix]

Available sources: :tesla, :finch, :phoenix. Only attach the sources you use.

Inbound path filtering

Only track requests under specific path prefixes:

config :monitorex, :inbound_path_prefixes, ["/api", "/graphql"]

When not configured, all paths are tracked.

Authentication & Access Control

Implement the Monitorex.Resolver behaviour to control dashboard access:

defmodule MyApp.MonitorexResolver do
  @behaviour Monitorex.Resolver

  @impl true
  def resolve_user(conn) do
    # Return a map with user info from your session/auth system
    case get_session(conn, :current_user) do
      nil -> %{id: nil, name: "guest"}
      user -> %{id: user.id, name: user.name}
    end
  end

  @impl true
  def resolve_access(%{id: nil}) do
    # Redirect unauthenticated users to login
    {:forbidden, "/login"}
  end

  def resolve_access(_user) do
    :all
  end
end

Configure it:

config :monitorex, :resolver, MyApp.MonitorexResolver

If no resolver is configured, a default resolver grants full access (:all).

Consumer Identification

Monitorex identifies inbound consumers by priority:

  1. Custom function — your own consumer_fn:
    config :monitorex, :consumer_fn, &MyApp.extract_consumer/1
  2. Basic-auth username — decoded from Authorization: Basic ...
  3. API key header — value of X-Api-Key (first 8 characters)

Deduplication

When both Tesla and Finch are used in the same application, the same HTTP request may fire events from both libraries. Enable dedup to prevent double-counting:

config :monitorex, :clients, [:tesla, :finch]

Request/Response Detail Capture

Monitorex can capture HTTP headers and bodies for detailed inspection.

Header redaction

Sensitive header values are automatically redacted before storage:

config :monitorex, :redacted_headers, [
  "authorization",
  "cookie",
  "set-cookie",
  "x-api-key",
  "x-auth-token"
]

Body storage

Body capture is disabled by default to limit memory usage:

# Store request and/or response bodies on the Event struct
config :monitorex, :store_request_body, true
config :monitorex, :store_response_body, true

# Truncate bodies larger than N bytes (default: 10_000)
config :monitorex, :max_body_bytes, 10_000

Pages

Page URL Description
Outbound Overview / Summary cards + host table
Outbound Recent /outbound_recent Live feed with status filter
Host Detail /host/:host Per-endpoint breakdown + recent requests
Inbound Overview /inbound Route table + summary
Inbound Consumers /inbound_consumers Per-consumer stats
Inbound Recent /inbound_recent Live feed with filters
Timeline /timeline Split-pane event inspector with request/response detail
Route Detail /route/:key Consumer breakdown + recent requests

Asset Pipeline

Monitorex ships pre-built CSS and JS assets. To rebuild them from source:

mix assets.build

Source files are in assets/css/app.css and assets/js/app.js. The build uses Tailwind CSS v4 and esbuild.

Development

git clone https://github.com/GustavoZiaugra/monitorex.git
cd monitorex
mix deps.get
mix compile --warnings-as-errors

# Run tests
mix test

# Run demo server
mix run scripts/demo.exs

# Validate as Phoenix dependency
cd /tmp
mix phx.new demo_monitorex --no-ecto --no-mailer --no-dashboard --no-gettext
cd demo_monitorex
# add {:monitorex, path: "/path/to/monitorex"} to mix.exs
mix deps.get && mix compile

Docs

mix docs

Then open doc/index.html.

License

MIT