Timeless

LiveDashboard Plugin for Timeless Metrics

Hex.pmDocsLicense


"I found it ironic that the first thing you do to time series data is squash the timestamp. That's how the name Timeless was born." --Mark Cotner

Telemetry reporter and LiveDashboard page plugin for TimelessMetrics.

Phoenix LiveDashboard ships real-time metrics that reset on every page load. TimelessMetricsDashboard bridges the gap: a telemetry reporter captures events into TimelessMetrics, and the dashboard page gives you persistent historical charts, alert visibility, backup controls, and compression stats.

Drop it in and your LiveDashboard gets real trending for free.

Installation

Quick Start (Igniter)

mix igniter.install timeless_metrics_dashboard

This automatically:

  1. Adds {TimelessMetricsDashboard, data_dir: "priv/timeless_metrics"} to your supervision tree
  2. Adds import TimelessMetricsDashboard.Router to your router
  3. Adds timeless_metrics_dashboard "/dashboard" to your browser scope
  4. Updates your .formatter.exs

Manual Setup

Add to your mix.exs:

def deps do
  [
    {:timeless_metrics, "~> 6.0"},
    {:timeless_metrics_dashboard, "~> 0.4"}
  ]
end

1. Supervision Tree

Add to your application's supervision tree. This starts TimelessMetrics and the telemetry reporter:

# application.ex
children = [
  {TimelessMetricsDashboard, data_dir: "priv/timeless_metrics"}
]

Or for more control over which metrics are captured:

children = [
  {TimelessMetricsDashboard,
    data_dir: "priv/timeless_metrics",
    metrics:
      TimelessMetricsDashboard.DefaultMetrics.vm_metrics() ++
      TimelessMetricsDashboard.DefaultMetrics.phoenix_metrics() ++
      TimelessMetricsDashboard.DefaultMetrics.ecto_metrics("my_app.repo") ++
      TimelessMetricsDashboard.DefaultMetrics.live_view_metrics()}
]

2. Router

# router.ex
import TimelessMetricsDashboard.Router

scope "/" do
  pipe_through :browser
  timeless_metrics_dashboard "/dashboard"
end

The router macro sets up LiveDashboard with the metrics history callback, the Timeless page, and the backup download plug.

3. Reporter Only (no Phoenix)

The reporter works without Phoenix. Any application that uses :telemetry can use it:

children = [
  {TimelessMetrics, name: :metrics, data_dir: "/var/lib/metrics"},
  {TimelessMetricsDashboard.Reporter,
    store: :metrics,
    metrics: TimelessMetricsDashboard.DefaultMetrics.vm_metrics()}
]

Dashboard Tabs

Overview

Store statistics at a glance: series count, total points, compression ratio, storage size, and rollup tier breakdown.

Metrics

Browse all metrics in the store (both telemetry-captured and directly written), select a time range, and view SVG charts with automatic bucketing. Metric metadata (type, unit, description) is displayed when available.

All metrics written to the TimelessMetrics store appear here, whether they came through the reporter or were written directly via TimelessMetrics.write/4.

Alerts

Lists all configured alert rules with their current state (ok/pending/firing). Includes inline documentation with examples for creating alerts via the TimelessMetrics API:

TimelessMetrics.create_alert(:timeless_metrics,
  name: "high_memory",
  metric: "telemetry.vm.memory.total",
  condition: :above,
  threshold: 512_000_000,
  duration: 60
)

# With webhook notification (ntfy.sh, Slack, etc.)
TimelessMetrics.create_alert(:timeless_metrics,
  name: "high_latency",
  metric: "telemetry.phoenix.endpoint.stop.duration",
  condition: :above,
  threshold: 500,
  duration: 120,
  aggregate: :avg,
  webhook_url: "https://ntfy.sh/my-alerts"
)

Storage

Database path, size, and retention settings. Create and download backups, flush buffered data to disk.

Child Spec Options

Option Default Description
:name:timeless_metrics TimelessMetrics store name
:data_dir"priv/timeless_metrics" Data directory
:metricsDefaultMetrics.metrics() List of Telemetry.Metrics structs
:reporter[] Extra opts forwarded to Reporter (:flush_interval, :prefix)

Reporter Options

Option Default Description
:storerequired TimelessMetrics store name (atom)
:metrics[] List of Telemetry.Metrics structs
:flush_interval10_000 Milliseconds between batch flushes
:prefix"telemetry" Metric name prefix
:nameTimelessMetricsDashboard.Reporter GenServer name

Page Options

Option Default Description
:storerequired TimelessMetrics store name (atom)
:chart_width700 SVG chart width in pixels
:chart_height250 SVG chart height in pixels
:download_pathnil Path to DownloadPlug (enables download links)

Default Metrics

Pre-built metric definitions for common events:

Mix and match with your own custom Telemetry.Metrics definitions.

Architecture

The reporter handler runs in the caller's process, not the GenServer. All hot-path operations are lock-free:

Demo

Run the included demo to see everything in action:

cd timeless_metrics_dashboard
mix run examples/demo.exs
# Open http://localhost:4000/dashboard/timeless

VM metrics will start populating immediately via :telemetry_poller. Use TIMELESS_DATA_DIR to persist data across restarts:

TIMELESS_DATA_DIR=~/.timeless_demo mix run examples/demo.exs

License

MIT