

TelemetryUI — telemetry\_ui v4.1.0

 try {

 var settings = JSON.parse(localStorage.getItem('ex\_doc:settings') || '{}');

 if (settings.theme === 'dark' ||

 ((settings.theme === 'system' || settings.theme == null) &&

 window.matchMedia('(prefers-color-scheme: dark)').matches)

 ) {

 document.body.classList.add('dark')

 }

 } catch (error) { }

 

Settings

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L1 "View Source")

TelemetryUI

(telemetry\_ui v4.1.0)

======================================================================================================================================================

Main entry point to start all the processes as part of your application.

Usage

=====

```

use Application

def start(\_type, \_args) do

 children = [

 Shopcast.Repo,

 MyAppWeb.Endpoint,

 {TelemetryUI, my\_config()}

 ]

```

The reporter, write buffer and pruner processes will be part of your supervision tree, ensuring that everything runs smoothly.

The config is a data structure representing all settings used by TelemetryUI.

[Config example](#module-config-example)

-----------------------------------------

```

 [

 metrics: [

 {"System", [last\_value("vm.memory.total", unit: {:byte, :megabyte})]}

 ],

 theme: %{title: "Metrics"},

 backend: 

 %TelemetryUI.Backend.EctoPostgres{

 repo: MyApp.Repo,

 pruner\_threshold: [months: -1],

 pruner\_interval\_ms: 3\_600\_000,

 max\_buffer\_size: 1\_000,

 flush\_interval\_ms: 10\_000

 }

 ]

```

This config will show a basic "last value" chart for the memory usage reported by the VM.

The title of the page will be "Metrics" and the backend used to store and query metrics will be PostgreSQL.

See [`TelemetryUI.Config`](TelemetryUI.Config.html) for a list of all options.

[Metrics list](#module-metrics-list)

-------------------------------------

Every kind of metrics exposed by `TelemetryMetrics` is supported by [`TelemetryUI`](TelemetryUI.html#content):

* `last_value`

* `summary`

* `sum`

* `counter`

* `distribution`

[`TelemetryUI`](TelemetryUI.html#content) also exposes its own set of metrics:

* `average`

* `average_over_time`

* `count_over_time`

* `median`

* `median_over_time`

[The Web](#module-the-web)

---------------------------

Finally, when the configuration is done and we actually want to see our metrics, we need to add the [`TelemetryUI.Web`](TelemetryUI.Web.html) module in our router:

*Phoenix*

```

scope "/" do

 pipe\_through([:browser])

 get("/metrics", TelemetryUI.Web, [], [assigns: %{telemetry\_ui\_allowed: true}])

end

```

The metrics page is protected by default. It needs to have the `telemetry_ui_allowed` assign to true to render.

We can imagine having a `:admin_protected` plug that ensure a user is an admin and also assign `telemetry_ui_allowed` to true.

```

scope "/" do

 pipe\_through([:browser, :admin\_protected])

 get("/metrics", TelemetryUI.Web, [])

end

```

That’s it! The `/metrics` page will show the metrics as they are recorded. Checkout the Guides to dive into more complex configuration and awesome features :)

[Summary](#summary)

====================

[Functions](#functions)

------------------------

[backend(name)](#backend/1)

[child\_spec(init\_arg)](#child_spec/1)

Returns a specification to start this module under a supervisor.

[config\_name(name)](#config_name/1)

[insert\_metric\_data(name, event)](#insert_metric_data/2)

[metric\_by\_id(name, id)](#metric_by_id/2)

[metric\_data(name, metric, filters)](#metric_data/3)

[page\_by\_id(name, id)](#page_by_id/2)

[page\_by\_title(name, title)](#page_by_title/2)

[pages(name)](#pages/1)

[start\_link(opts)](#start_link/1)

[theme(name)](#theme/1)

[valid\_share\_key?(share\_key)](#valid_share_key?/1)

[valid\_share\_url?(url)](#valid_share_url?/1)

[writer\_buffer\_name(name)](#writer_buffer_name/1)

[Functions](#functions)

========================

[Link to this function](#backend/1 "Link to this function")

backend(name)

=============

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L193 "View Source")

[Link to this function](#child_spec/1 "Link to this function")

child\_spec(init\_arg)

======================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L132 "View Source")

Returns a specification to start this module under a supervisor.

See [`Supervisor`](https://hexdocs.pm/elixir/Supervisor.html).

[Link to this function](#config_name/1 "Link to this function")

config\_name(name)

==================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L211 "View Source")

[Link to this function](#insert_metric_data/2 "Link to this function")

insert\_metric\_data(name, event)

=================================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L185 "View Source")

[Link to this function](#metric_by_id/2 "Link to this function")

metric\_by\_id(name, id)

========================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L202 "View Source")

[Link to this function](#metric_data/3 "Link to this function")

metric\_data(name, metric, filters)

===================================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L181 "View Source")

[Link to this function](#page_by_id/2 "Link to this function")

page\_by\_id(name, id)

======================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L199 "View Source")

[Link to this function](#page_by_title/2 "Link to this function")

page\_by\_title(name, title)

============================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L200 "View Source")

[Link to this function](#pages/1 "Link to this function")

pages(name)

===========

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L189 "View Source")

[Link to this function](#start_link/1 "Link to this function")

start\_link(opts)

=================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L110 "View Source")

[Link to this function](#theme/1 "Link to this function")

theme(name)

===========

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L191 "View Source")

[Link to this function](#valid_share_key?/1 "Link to this function")

valid\_share\_key?(share\_key)

==============================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L195 "View Source")

[Link to this function](#valid_share_url?/1 "Link to this function")

valid\_share\_url?(url)

=======================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L197 "View Source")

[Link to this function](#writer_buffer_name/1 "Link to this function")

writer\_buffer\_name(name)

==========================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui.ex#L210 "View Source")





TelemetryUI.Backend — telemetry\_ui v4.1.0

 try {

 var settings = JSON.parse(localStorage.getItem('ex\_doc:settings') || '{}');

 if (settings.theme === 'dark' ||

 ((settings.theme === 'system' || settings.theme == null) &&

 window.matchMedia('(prefers-color-scheme: dark)').matches)

 ) {

 document.body.classList.add('dark')

 }

 } catch (error) { }

 

Settings

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/backend.ex#L1 "View Source")

TelemetryUI.Backend protocol

(telemetry\_ui v4.1.0)

=======================================================================================================================================================================================

Inserting, fetching and pruning of metrics.

[Inserting](#module-inserting)

-------------------------------

Inserting is called by the internal `WriteBuffer`. It can be grouped depending on the buffer configuration inside the backend struct:

* `flush_interval_ms`: Time interval before the write buffer calls the backend

* `max_buffer_size`: Maximum count of events before the write buffer calls the backend

[Fetching](#module-fetching)

-----------------------------

Fetching is called when rendering metrics in the view. The `filters` argument is a struct with predefined fields: `to`, `from`, `event_name` and `compare`.

[Pruning](#module-pruning)

---------------------------

Pruning is implemented to keep the datastore clean. Keeping data forever will increase the size of the storage and affect performance.

* `pruner_threshold`: *Example:* `[months: -1]`. Delete events older than a month.

* `pruner_interval_ms`: *Example:* 84\_000. Time interval for the pruner process to run. The process simply calls `#prune_events!/2`.

[Summary](#summary)

====================

[Types](#types)

----------------

[t()](#t:t/0)

[Functions](#functions)

------------------------

[insert\_event(backend, value, date, event\_name, tags \\ %{}, count \\ 1)](#insert_event/6)

[metric\_data(backend, metric, filters)](#metric_data/3)

[prune\_events!(backend, datetime)](#prune_events!/2)

[Types](#types)

================

[Link to this type](#t:t/0 "Link to this type")

t()

===

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/backend.ex#L1 "View Source")

```

@type t() :: [term](https://hexdocs.pm/elixir/typespecs.html#built-in-types)()

```

[Functions](#functions)

========================

[Link to this function](#insert_event/6 "Link to this function")

insert\_event(backend, value, date, event\_name, tags \\ %{}, count \\ 1)

=========================================================================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/backend.ex#L19 "View Source")

[Link to this function](#metric_data/3 "Link to this function")

metric\_data(backend, metric, filters)

======================================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/backend.ex#L21 "View Source")

[Link to this function](#prune_events!/2 "Link to this function")

prune\_events!(backend, datetime)

=================================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/backend.ex#L20 "View Source")





TelemetryUI.Backend.EctoPostgres.Migrations — telemetry\_ui v4.1.0

 try {

 var settings = JSON.parse(localStorage.getItem('ex\_doc:settings') || '{}');

 if (settings.theme === 'dark' ||

 ((settings.theme === 'system' || settings.theme == null) &&

 window.matchMedia('(prefers-color-scheme: dark)').matches)

 ) {

 document.body.classList.add('dark')

 }

 } catch (error) { }

 

Settings

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/ecto_postgres/migrations.ex#L1 "View Source")

TelemetryUI.Backend.EctoPostgres.Migrations

(telemetry\_ui v4.1.0)

=======================================================================================================================================================================================================================

Migrations create and modify the database tables TelemetryUI needs to function.

[Usage](#module-usage)

-----------------------

To use migrations in your application you'll need to generate an [`Ecto.Migration`](https://hexdocs.pm/ecto_sql/3.10.1/Ecto.Migration.html) that wraps

calls to [`TelemetryUI.Backend.EctoPostgres.Migrations`](TelemetryUI.Backend.EctoPostgres.Migrations.html#content):

```

mix ecto.gen.migration add\_telemetry\_ui

```

Open the generated migration in your editor and call the `up` and `down` functions on

[`TelemetryUI.Backend.EctoPostgres.Migrations`](TelemetryUI.Backend.EctoPostgres.Migrations.html#content):

```

defmodule MyApp.Repo.Migrations.AddTelemetryUI do

 use Ecto.Migration

 def up, do: TelemetryUI.Backend.EctoPostgres.Migrations.up()

 def down, do: TelemetryUI.Backend.EctoPostgres.Migrations.down()

end

```

This will run all of TelemetryUI's versioned migrations for your database.

Now, run the migration to create the table:

```

mix ecto.migrate

```

Migrations between versions are idempotent. As new versions are released, you

may need to run additional migrations. To do this, generate a new migration:

```

mix ecto.gen.migration upgrade\_telemetry\_ui\_to\_v11

```

Open the generated migration in your editor and call the `up` and `down`

functions on [`TelemetryUI.Backend.EctoPostgres.Migrations`](TelemetryUI.Backend.EctoPostgres.Migrations.html#content), passing a version number:

```

defmodule MyApp.Repo.Migrations.UpgradeTelemetryUIToV11 do

 use Ecto.Migration

 def up, do: TelemetryUI.Backend.EctoPostgres.Migrations.up(version: 11)

 def down, do: TelemetryUI.Backend.EctoPostgres.Migrations.down(version: 11)

end

```

[Isolation with Prefixes](#module-isolation-with-prefixes)

-----------------------------------------------------------

TelemetryUI supports namespacing through PostgreSQL schemas, also called "prefixes" in Ecto. With

prefixes your events table can reside outside of your primary schema (usually public) and you can

have multiple separate job tables.

To use a prefix you first have to specify it within your migration:

```

defmodule MyApp.Repo.Migrations.AddPrefixedTelemetryUIJobsTable do

 use Ecto.Migration

 def up, do: TelemetryUI.Backend.EctoPostgres.Migrations.up(prefix: "private")

 def down, do: TelemetryUI.Backend.EctoPostgres.Migrations.down(prefix: "private")

end

```

The migration will create the "private" schema and all tables, functions and triggers within

that schema. With the database migrated you'll then specify the prefix in your configuration:

```

config :my\_app, TelemetryUI,

 prefix: "private",

 ...

```

In some cases, for example if your "private" schema already exists and your database user in

production doesn't have permissions to create a new schema, trying to create the schema from the

migration will result in an error. In such situations, it may be useful to inhibit the creation

of the "private" schema:

```

defmodule MyApp.Repo.Migrations.AddPrefixedTelemetryUIJobsTable do

 use Ecto.Migration

 def up, do: TelemetryUI.Backend.EctoPostgres.Migrations.up(prefix: "private", create\_schema: false)

 def down, do: TelemetryUI.Backend.EctoPostgres.Migrations.down(prefix: "private")

end

```

[Summary](#summary)

====================

[Functions](#functions)

------------------------

[down(opts \\ [])](#down/1)

Run the `down` changes for all migrations between the current version and the initial version.

[up(opts \\ [])](#up/1)

Run the `up` changes for all migrations between the initial version and the current version.

[Functions](#functions)

========================

[Link to this function](#down/1 "Link to this function")

down(opts \\ [])

================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/ecto_postgres/migrations.ex#L158 "View Source")

Run the `down` changes for all migrations between the current version and the initial version.

[Example](#down/1-example)

---------------------------

Run all migrations from current version down to the first:

```

TelemetryUI.Backend.EctoPostgres.Migrations.down()

```

Run migrations down to and including a specified version:

```

TelemetryUI.Backend.EctoPostgres.Migrations.down(version: 5)

```

Run migrations in an alternate prefix:

```

TelemetryUI.Backend.EctoPostgres.Migrations.down(prefix: "payments")

```

[Link to this function](#up/1 "Link to this function")

up(opts \\ [])

==============

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/backend/ecto_postgres/migrations.ex#L125 "View Source")

Run the `up` changes for all migrations between the initial version and the current version.

[Example](#up/1-example)

-------------------------

Run all migrations up to the current version:

```

TelemetryUI.Backend.EctoPostgres.Migrations.up()

```

Run migrations up to a specified version:

```

TelemetryUI.Backend.EctoPostgres.Migrations.up(version: 2)

```

Run migrations in an alternate prefix:

```

TelemetryUI.Backend.EctoPostgres.Migrations.up(prefix: "payments")

```

Run migrations in an alternate prefix but don't try to create the schema:

```

TelemetryUI.Backend.EctoPostgres.Migrations.up(prefix: "payments", create\_schema: false)

```





TelemetryUI.Config — telemetry\_ui v4.1.0

 try {

 var settings = JSON.parse(localStorage.getItem('ex\_doc:settings') || '{}');

 if (settings.theme === 'dark' ||

 ((settings.theme === 'system' || settings.theme == null) &&

 window.matchMedia('(prefers-color-scheme: dark)').matches)

 ) {

 document.body.classList.add('dark')

 }

 } catch (error) { }

 

Settings

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/config.ex#L1 "View Source")

TelemetryUI.Config

(telemetry\_ui v4.1.0)

====================================================================================================================================================================

Holds the state of the config.

See other modules for more details:

* [`TelemetryUI.Theme`](TelemetryUI.Theme.html)

* [`TelemetryUI.Backend`](TelemetryUI.Backend.html)

[Summary](#summary)

====================

[Functions](#functions)

------------------------

[child\_spec(init\_arg)](#child_spec/1)

Returns a specification to start this module under a supervisor.

[start\_link(initial\_state)](#start_link/1)

[Functions](#functions)

========================

[Link to this function](#child_spec/1 "Link to this function")

child\_spec(init\_arg)

======================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/config.ex#L10 "View Source")

Returns a specification to start this module under a supervisor.

See [`Supervisor`](https://hexdocs.pm/elixir/Supervisor.html).

[Link to this function](#start_link/1 "Link to this function")

start\_link(initial\_state)

===========================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/config.ex#L12 "View Source")





TelemetryUI.Theme — telemetry\_ui v4.1.0

 try {

 var settings = JSON.parse(localStorage.getItem('ex\_doc:settings') || '{}');

 if (settings.theme === 'dark' ||

 ((settings.theme === 'system' || settings.theme == null) &&

 window.matchMedia('(prefers-color-scheme: dark)').matches)

 ) {

 document.body.classList.add('dark')

 }

 } catch (error) { }

 

Settings

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/theme.ex#L1 "View Source")

TelemetryUI.Theme

(telemetry\_ui v4.1.0)

==================================================================================================================================================================

Customize the UI of the web view.

* `primary_color`: *Example: #ff0000*, Used for the title and first color on the charts

* `title`: *Example: "My metrics"*, Used for the HTML page title and the title in the header.

* `description`: *Example: "HTTP, GraphQL and Database metrics"*, Used for the HTML description tag.

* `logo`: SVG logo in string used for the favicon and header.

* `scale`: List of hex colors used in the charts.

* `share_key`: 16 characters string used to hash the shared page.

* `share_path`: Path in string starting by a `/` used to generate the shared page. It’s difference from the metrics page since it does not require authentication.

* `frame_options`: *Example: [{:last\_30\_minutes, 30, :minute}, {:last\_2\_hours, 120, :minute}]*, Used to generate the time frame in the header.





TelemetryUI.Web — telemetry\_ui v4.1.0

 try {

 var settings = JSON.parse(localStorage.getItem('ex\_doc:settings') || '{}');

 if (settings.theme === 'dark' ||

 ((settings.theme === 'system' || settings.theme == null) &&

 window.matchMedia('(prefers-color-scheme: dark)').matches)

 ) {

 document.body.classList.add('dark')

 }

 } catch (error) { }

 

Settings

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/web/web.ex#L1 "View Source")

TelemetryUI.Web

(telemetry\_ui v4.1.0)

==================================================================================================================================================================

Plug to render an HTML view with all metrics.

The view handles the different pages in the configurationa and the assets pipeline for CSS and JavaScript.

The module also handles "async" components data request called in the components.

[Summary](#summary)

====================

[Functions](#functions)

------------------------

[call(conn, opts)](#call/2)

Callback implementation for [`Plug.call/2`](https://hexdocs.pm/plug/1.14.2/Plug.html#c:call/2).

[index(conn, arg2)](#index/2)

[init(opts)](#init/1)

Callback implementation for [`Plug.init/1`](https://hexdocs.pm/plug/1.14.2/Plug.html#c:init/1).

[Functions](#functions)

========================

[Link to this function](#call/2 "Link to this function")

call(conn, opts)

================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/web/web.ex#L8 "View Source")

Callback implementation for [`Plug.call/2`](https://hexdocs.pm/plug/1.14.2/Plug.html#c:call/2).

[Link to this function](#index/2 "Link to this function")

index(conn, arg2)

=================

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/web/web.ex#L24 "View Source")

[Link to this function](#init/1 "Link to this function")

init(opts)

==========

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/lib/telemetry_ui/web/web.ex#L8 "View Source")

Callback implementation for [`Plug.init/1`](https://hexdocs.pm/plug/1.14.2/Plug.html#c:init/1).





README — telemetry\_ui v4.1.0

 try {

 var settings = JSON.parse(localStorage.getItem('ex\_doc:settings') || '{}');

 if (settings.theme === 'dark' ||

 ((settings.theme === 'system' || settings.theme == null) &&

 window.matchMedia('(prefers-color-scheme: dark)').matches)

 ) {

 document.body.classList.add('dark')

 }

 } catch (error) { }

 

Settings

[View Source](https://github.com/mirego/telemetry_ui/blob/v4.1.0/README.md#L1 "View Source")

README

================================================================================================================

 ![](https://user-images.githubusercontent.com/464900/183483800-f313a3c0-1877-4c37-ac07-e08bed3f2276.png)

  

  

 Telemetry-based metrics UI. Take your [`telemetry`](https://github.com/beam-telemetry/telemetry) metrics and display them in a web page.

   

  

[![](https://img.shields.io/hexpm/v/telemetry_ui.svg)](https://hex.pm/packages/telemetry_ui)

[Features](#features)

----------------------

[`TelemetryUI`](TelemetryUI.html)’s primary goal is to display [your application metrics](https://hexdocs.pm/telemetry_metrics) without external infrastructure dependencies. [Plug](https://hexdocs.pm/plug/Plug.Telemetry.html), [Phoenix](https://hexdocs.pm/phoenix/telemetry.html), [Phoenix LiveView](https://hexdocs.pm/phoenix_live_view/telemetry.html), [Absinthe](https://hexdocs.pm/absinthe/telemetry.html), [Ecto](https://hexdocs.pm/ecto/Ecto.Repo.html#module-telemetry-events), [Erlang VM](https://hexdocs.pm/telemetry_poller/readme.html), [Tesla](https://hexdocs.pm/tesla/Tesla.Middleware.Telemetry.html), [Finch](https://hexdocs.pm/finch/Finch.Telemetry.html), [Redix](https://hexdocs.pm/redix/telemetry.html), [Oban](https://hexdocs.pm/oban/Oban.Telemetry.html), [Broadway](https://hexdocs.pm/broadway/Broadway.html#module-telemetry) and others expose all sorts of data that can be useful. You can also emit your own events from your application.

Your data should not have to be uploaded somewhere else to have insighful metrics.

It comes with a Postgres backend, powered by [Ecto](https://hexdocs.pm/ecto), to quickly (and efficiently) store and query your application events.

![Screenshot of /metrics showcasing values and charts](https://user-images.githubusercontent.com/464900/205386716-a4aa9387-6125-40e6-b764-b2e76df5e83b.png)### 

[Advantages over other tools](#advantages-over-other-tools)

* Persisted metrics inside your own database

* Live dashboard

* Many built-in charts and visualizations using [VegaLite](https://vega.github.io/vega-lite/)

### 

[Advanced features](#advanced-features)

* 100% custom UI hook to show your own components

* 100% custom data fetching to show live data

* Shareable metrics page (secured, cacheable, without external requests)

* Slack digest with rendered images

* Multiple metrics dashboard living in the same app

Checkout the Guides for more informations.

[Usage](#usage)

----------------

### 

[Installation](#installation)

TelemetryUI is published on Hex. Add it to your list of dependencies in `mix.exs`:

```

# mix.exs

def deps do

 [

 {:telemetry\_ui, "~> 4.0"}

 ]

end

```

Then run mix deps.get to install Telemetry and its dependencies.

After the packages are installed you must create a database migration to add the `telemetry_ui_events` table to your database:

```

mix ecto.gen.migration add\_telemetry\_ui\_events\_table

```

Open the generated migration in your editor and call the up and down functions on `TelemetryUI.Adapter.EctoPostgres.Migrations`:

```

defmodule MyApp.Repo.Migrations.AddTelemetryUIEventsTable do

 use Ecto.Migration

 def up do

 TelemetryUI.Backend.EctoPostgres.Migrations.up()

 end

 # We specify `version: 1` in `down`, ensuring that we'll roll all the way back down if

 # necessary, regardless of which version we've migrated `up` to.

 def down do

 TelemetryUI.Backend.EctoPostgres.Migrations.down(version: 1)

 end

end

```

This will run all of TelemetryUI's versioned migrations for your database. Migrations between versions are idempotent and rarely change after a release. As new versions are released you may need to run additional migrations.

Now, run the migration to create the table:

```

mix ecto.migrate

```

TelemetryUI instances are isolated supervision trees and must be included in your application's supervisor to run. Use the application configuration you've just set and include TelemetryUI in the list of supervised children:

```

# lib/my\_app/application.ex

def start(\_type, \_args) do

 children = [

 MyApp.Repo,

 {TelemetryUI, telemetry\_config()}

 ]

 Supervisor.start\_link(children, strategy: :one\_for\_one, name: MyApp.Supervisor)

end

defp telemetry\_config do

 import TelemetryUI.Metrics

 [

 metrics: [

 last\_value("my\_app.users.total\_count", description: "Number of users", ui\_options: [unit: " users"]),

 counter("phoenix.router\_dispatch.stop.duration", description: "Number of requests", unit: {:native, :millisecond}, ui\_options: [unit: " requests"]),

 value\_over\_time("vm.memory.total", unit: {:byte, :megabyte}),

 distribution("phoenix.router\_dispatch.stop.duration", description: "Requests duration", unit: {:native, :millisecond}, reporter\_options: [buckets: [0, 100, 500, 2000]]),

 ],

 backend: %TelemetryUI.Backend.EctoPostgres{

 repo: MyApp.Repo,

 pruner\_threshold: [months: -1],

 pruner\_interval\_ms: 84\_000,

 max\_buffer\_size: 10\_000,

 flush\_interval\_ms: 10\_000

 }

 ]

end

```

Since the config is read once at startup, you need to restart the server of you add new metrics to track.

To see the rendered metrics, you need to add a route to your router.

```

# lib/my\_app\_web/router.ex

scope "/" do

 get("/metrics", TelemetryUI.Web, [], [assigns: %{telemetry\_ui\_allowed: true}])

end

```

#### Security

Since it may contain sensitive data, [`TelemetryUI`](TelemetryUI.html) requires a special assign to render the page.

`:telemetry_ui_allowed` must be set to `true` in the `conn` struct before it enters the [`TelemetryUI.Web`](TelemetryUI.Web.html) module.

By using a special assign to control access, you can integrate [`TelemetryUI.Web`](TelemetryUI.Web.html) page with your existing authorization. We can imagine an admin protected section that also gives you access to the [`TelemetryUI.Web`](TelemetryUI.Web.html) page:

```

pipeline :admin\_protected do

 plug(MyAppWeb.EnsureCurrentUser)

 plug(MyAppWeb.EnsureRole, :admin)

 plug(:enable\_telemetry\_ui)

end

def enable\_telemetry\_ui(conn, \_), do: assign(conn, :telemetry\_ui\_allowed, true)

```

That’s it! You can declare as many metrics as you want and they will render in HTML on your page!

[License](#license)

--------------------

[`TelemetryUI`](TelemetryUI.html) is © 2023 [Mirego](https://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/telemetry_ui/blob/master/LICENSE.md) file.

[About Mirego](#about-mirego)

------------------------------

[Mirego](https://www.mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. We’re a team of [talented people](https://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](http://www.mirego.org).

We also [love open-source software](https://open.mirego.com) and we try to give back to the community as much as we can.

[← Previous Page

 

API Reference](api-reference.html)

[Next Page →

 

Using application data](application-data.html)

