View Source README
features
Features
telemetry_ui
’s primary goal is to display your application metrics without external infrastructure dependencies. Phoenix, Absinthe, Ecto, Erlang VM, Tesla, Redix, Oban 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, to quickly (and efficiently) store and query your application events.

3-0-breaking-change
3.0 breaking change
The 3.0
version adds the possibility to render component as image. We renamed Component.render
protocol callback to to_html
to add the to_image
callback.
If you have a custom component, you juste need to rename def render/2
to def to_html/2
.
2-0-breaking-change
2.0 breaking change
The 2.0
version fixes a hack that was introduced to register unique event name based on the keep
and drop
options.
Since the name is used to register the event like counter("phoenix.router_dispatch.stop.duration"
, we added a reporter_options: [report_as: "some unique name"]
. But the way to actually do this is documented here: https://hexdocs.pm/telemetry_metrics/Telemetry.Metrics.html#module-filtering-on-metadata. So in 2.0
, we removed the report_as
option to use the event_name
option on every metric definition.
1.x:
distribution(
"http.client.request.duration",
reporter_options: [report_as: "fast_client"],
keep: &(match?(%{name: :fast_client}, &1))
)
2.x:
distribution(
"http.fast.client.request.duration",
event_name: [:http_client, :request, :stop],
keep: &(match?(%{name: :fast_client}, &1))
)
This changes impact the unique index on the database, so you can either manually delete every metrics with a report_as
before running the 2.0
migration, or truncate the table.
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, ">= 0.0.1"}
]
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
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
module.
By using a special assign to control access, you can integrate TelemetryUI.Web
page with your existing authorization. We can imagine an admin protected section that also gives you access to the TelemetryUI.Web
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
is © 2022 Mirego and may be freely distributed under the New BSD license. See the LICENSE.md
file.
about-mirego
About Mirego
Mirego 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 who imagine and build beautiful Web and mobile applications. We come together to share ideas and change the world.
We also love open-source software and we try to give back to the community as much as we can.