Packages
prom_ex
0.1.2-alpha
1.12.0
1.11.0
1.10.0
1.9.0
1.8.0
1.7.1
1.7.0
retired
1.6.0
1.5.0
1.4.1
1.4.0
1.3.0
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
0.1.15-beta
0.1.14-beta
0.1.13-beta
0.1.12-beta
0.1.11-alpha
0.1.10-alpha
0.1.9-alpha
0.1.8-alpha
0.1.7-alpha
0.1.6-alpha
0.1.5-alpha
0.1.4-alpha
0.1.3-alpha
0.1.2-alpha
0.1.1-alpha
0.1.0-alpha
Prometheus metrics and Grafana dashboards for all of your favorite Elixir libraries
Current section
Files
Jump to
Current section
Files
README.md
# PromEx[](http://hex.pm/packages/prom_ex) [](https://github.com/akoutmos/prom_ex/actions) [](https://coveralls.io/github/akoutmos/prom_ex?branch=master)<img align="center" width="33%" src="guides/images/logo.svg" alt="PromEx" style="margin-left:33%">An Elixir Prometheus metrics collection library built on top of Telemetry<br># Contents- [Installation](#installation)- [Design Philosophy](#design-philosophy)- [Available Plugins](#available-plugins)- [Setting Up Metrics](#setting-up-metrics)- [Performance Concerns](#performance-concerns)- [Attribution](#attribution)## InstallationThis library is still under active development with changing API contracts and forked dependencies...use at your ownrisk for now :).[Available in Hex](https://hex.pm/packages/prom_ex), the package can be installed by adding `prom_ex`to your list of dependencies in `mix.exs`:```elixirdef deps do [ {:prom_ex, "~> 0.1.1-alpha"} ]end```Documentation can be found at [https://hexdocs.pm/prom_ex](https://hexdocs.pm/prom_ex).### Design PhilosophyWith the widespread adoption of the Telemetry library and the other libraries in the [BEAM Telemetry GitHubOrg](https://github.com/beam-telemetry), we have reached a point where we have a consistent means of surfacingapplication metrics. This allows us to have a great level of insight into our applications and dependencies given thatthey all leverage the same fundamental tooling. The goal of this project is to provide a "Plug-in" style library whereyou can easily add new plug-ins to surface metrics so that Prometheus can scrape them. Ideally, this project acts as the"Metrics" pillar in your application (in reference to [The Three Pillars ofObservability](https://www.oreilly.com/library/view/distributed-systems-observability/9781492033431/ch04.html)).To this end, while PromEx does provide a certain level of configurability (like the polling rate, starting behaviour formanual metrics and all the options that the plugins receive), the goal is not to make an infinitely configurable tool.For example, you are not able to edit the names/descriptions of Prometheus metrics via plugin options or even the tagsthat are attached to the data points.Instead, if there things that you don't agree with or that are incompatible with your usage of a certain 1st partyplugin and want to edit how the PromEx plugins react to Telemetry events, it is recommended that you fork the plugin inquestion and edit it to your specific use case. If you think that the community can benefit for your changes, do nothesitate to make a PR and I'll be sure to review it. This is not to say that event configurability will never come toPromEx, but I want to make sure that the public facing API is clean and straightforward and not bogged down withconfiguration. That and the Grafana dashboards would then have to become templatized to accommodate all thisconfigurability.PromEx provides a few utilities to you in order to accomplish this goal:- A behaviour that defines the contract for PromEx plug-ins- Mix tasks to upload the provided complimentary Grafana dashboards- The `PromEx.MetricTypes.Event` struct to define event based metrics- The `PromEx.MetricTypes.Polling` struct to define pollable metrics- The `PromEx.MetricTypes.Manual` struct to define manually refreshed metrics- The `PromEx.Plug` module that can be used in your Phoenix or Plug application to expose the collected metrics### Available Plugins| Plugin | Status | Description || ---------------------------- | ----------- | ------------------------------------------------------ || `PromEx.Plugins.Application` | Alpha | Collect metrics on your application dependencies || `PromEx.Plugins.Beam` | Alpha | Collect metrics regarding the BEAM virtual machine || `PromEx.Plugins.Phoenix` | Alpha | Collect request metrics emitted by Phoenix || `PromEx.Plugins.Ecto` | Coming soon | Collect query metrics emitted by Ecto || `PromEx.Plugins.Broadway` | Coming soon | Collect message processing metrics emitted by Broadway || `PromEx.Plugins.Finch` | Coming soon | Collect HTTP request metrics emitted by Finch || More coming soon... | | |### Setting Up MetricsThe goal of PromEx is to have metrics set up be as simple and streamlined as possible. In that spirit, allthat you need to do to start leveraging PromEx along with the built-in plugins is the following in your`application.ex` file:```elixirdefmodule MyCoolApp.Application do use Application def start(_type, _args) do children = [ ... { PromEx, delay_manual_start: :no_delay, drop_metrics_groups: [:phoenix_channel_event_metrics], plugins: [ {PromEx.Plugins.Phoenix, router: WebAppWeb.Router}, PromEx.Plugins.Beam, {PromEx.Plugins.Application, [otp_app: :web_app]} ] } ] opts = [strategy: :one_for_one, name: MyCoolApp.Supervisor] Supervisor.start_link(children, opts) endend```With that in place, all that you need to do is then add the PromEx plug somewhere in your`endpoint.ex` file (I would suggest putting it before your `plug Plug.Telemetry` call so thatyou do not pollute your logs with calls to `/metrics`):```elixirdefmodule MyCoolAppWeb.Endpoint do use Phoenix.Endpoint, otp_app: :my_cool_app ... plug PromEx.Plug # Or plug PromEx.plug, path: "/some/other/non-standard/path" ... plug Plug.RequestId plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint] ... plug MyCoolAppWeb.Routerend```With that in place, all you need to do is start your server and you should be able to hit yourmetrics endpoint and see your application metrics:```terminal$ curl localhost:4000/metrics# HELP my_cool_app_application_dependency_info Information regarding the application's dependencies.# TYPE my_cool_app_application_dependency_info gaugemy_cool_app_application_dependency_info{modules="69",name="hex",version="0.20.5"} 1my_cool_app_application_dependency_info{modules="1",name="connection",version="1.0.4"} 1my_cool_app_application_dependency_info{modules="4",name="telemetry_poller",version="0.5.1"} 1......```Be sure to check out the module docs for each plugin that you choose to use to ensure that you are familiarwith all of the options that they provide.### Performance ConcernsYou may think to yourself that with all these metrics being collected and scraped, that the performance of yourapplication my be impacted. Luckily PromEx is built upon the solid foundation established by the `Telemetry`,`TelemetryMetrics`, and the `TelemetryMetricsPrometheus` projects. These libraries were designed to be as lightweightand performant as possible. From some basic stress tests that I have run, I have been unable to observe any meaningfulor measurable performance reduction (thank you OTP and particularly ETS ;)). Here are six sample stress tests using[wrk2](https://github.com/giltene/wrk2) with PromEx enabled and disabled with the following initializationconfiguration:```elixir{ PromEx, delay_manual_start: :no_delay, drop_metrics_groups: [:phoenix_channel_event_metrics], plugins: [ {PromEx.Plugins.Phoenix, router: WebAppWeb.Router}, PromEx.Plugins.Beam, {PromEx.Plugins.Application, [otp_app: :web_app]} ]}```With out PromEx metrics collection:```terminal$ wrk2 -t5 -c50 -R 1000 -d10s 'http://localhost:4000/'Running 10s test @ http://localhost:4000/ 5 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.25ms 1.02ms 22.00ms 71.90% Req/Sec -nan -nan 0.00 0.00% 10003 requests in 10.01s, 38.60MB readRequests/sec: 999.78Transfer/sec: 3.86MB$ wrk2 -t5 -c50 -R 1000 -d10s 'http://localhost:4000/'Running 10s test @ http://localhost:4000/ 5 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.15ms 0.92ms 15.06ms 67.75% Req/Sec -nan -nan 0.00 0.00% 10002 requests in 10.00s, 38.59MB readRequests/sec: 999.73Transfer/sec: 3.86MB$ wrk2 -t5 -c50 -R 1000 -d10s 'http://localhost:4000/'Running 10s test @ http://localhost:4000/ 5 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.23ms 1.31ms 29.82ms 84.14% Req/Sec -nan -nan 0.00 0.00% 10001 requests in 10.00s, 38.59MB readRequests/sec: 999.82Transfer/sec: 3.86MB```With PromEx metrics collection:```terminal$ wrk2 -t5 -c50 -R 1000 -d10s 'http://localhost:4000/'Running 10s test @ http://localhost:4000/ 5 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.55ms 1.69ms 36.86ms 94.40% Req/Sec -nan -nan 0.00 0.00% 9999 requests in 10.00s, 38.58MB readRequests/sec: 1000.11Transfer/sec: 3.86MB$ wrk2 -t5 -c50 -R 1000 -d10s 'http://localhost:4000/'Running 10s test @ http://localhost:4000/ 5 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.42ms 1.56ms 31.58ms 90.48% Req/Sec -nan -nan 0.00 0.00% 10004 requests in 10.00s, 38.60MB readRequests/sec: 999.93Transfer/sec: 3.86MB$ wrk2 -t5 -c50 -R 1000 -d10s 'http://localhost:4000/'Running 10s test @ http://localhost:4000/ 5 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.39ms 1.09ms 18.56ms 72.96% Req/Sec -nan -nan 0.00 0.00% 10001 requests in 10.00s, 38.59MB readRequests/sec: 999.81Transfer/sec: 3.86MB```### AttributionIt wouldn't be right to not include somewhere in this project a "thanks" to the various projects thathelped make this possible:- The various projects available in [BEAM Telemetry](https://github.com/beam-telemetry)- All of the Prometheus libraries that Ilya Khaprov ([@deadtrickster](https://github.com/deadtrickster)) maintains- The logo for the project is an edited version of an SVG image from the [unDraw project](https://undraw.co/)