# Prometheus.ex - Prometheus.io Elixir integrations

**URL:** <https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796>\
**Category:** Announcing\
**Tags:** ecto, erlang, library, prometheus\
**Created:** [September 27, 2016, 12:03pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796 "2016-09-27T12:03:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [September 27, 2016, 12:03pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/1 "2016-09-27T12:03:27Z")

</div>

I’ve just released stable versions of my Prometheus Elixir libs:

- [Elixir client](https://github.com/deadtrickster/prometheus.ex) [[docs]](https://hexdocs.pm/prometheus_ex/Prometheus.html);
- [Ecto collector](https://github.com/deadtrickster/prometheus-ecto) [[docs]](https://hexdocs.pm/prometheus_ecto/Prometheus.EctoInstrumenter.html);
- [Plugs instrumenter/Exporter](https://github.com/deadtrickster/prometheus-plugs) [[docs]](https://hexdocs.pm/prometheus_plugs/api-reference.html);
- [Phoenix instrumenter](https://github.com/deadtrickster/prometheus-phoenix) [[docs]](https://hexdocs.pm/prometheus_phoenix/Prometheus.PhoenixInstrumenter.html).

Elixir client is based on [Erlang client](https://github.com/deadtrickster/prometheus.erl) which exports dozens of metrics such as VM memory metrics, VM system info metrics, Mnesia metrics, etc.

For linux users there is also [Process info collector](https://github.com/deadtrickster/prometheus_process_collector).

I would be glad to answer any questions!

---

<div class="post-metadata">

**Author:** ![skosch](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/s/5daacb/32.png) [@skosch](https://forum.elixirforum.com/u/skosch)\
**Post date:** [September 30, 2016, 4:52pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/2 "2016-09-30T16:52:57Z")

</div>

For those new to monitoring (like myself), I wrote a blog post on how to set this up:

> **[aldusleaf.org](https://aldusleaf.org/monitoring-elixir-apps-in-2016-prometheus-and-grafana/)**

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [September 30, 2016, 5:34pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/3 "2016-09-30T17:34:58Z")

</div>

Thank you! Excellent post. Just a note: `prometheus_plugs` can also instrument a single plug or it’s own pipeline:

```elixir
defmodule EnsureAuthenticatedInstrumenter do
  use Prometheus.PlugInstrumenter

  plug Guardian.Plug.EnsureAuthenticated

  def label_value(:authenticated, {conn, _}) do
    conn.status != 401
  end
end

```

Basically it uses Plug.Builder and similar to it in this aspect.

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [October 3, 2016, 10:00am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/4 "2016-10-03T10:00:56Z")

</div>

I just pushed version 3.0.1 of Prometheus.erl with huge performance update:

 ![](https://forum.elixirforum.com/uploads/default/original/2X/3/38b66b99ad9c132c30d2a12710723d68763676f0.png)

Run `mix deps.update prometheus` to update!

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [October 21, 2016, 11:23am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/5 "2016-10-21T11:23:06Z")

</div>

Update:

- [Prometheus.ex](https://github.com/deadtrickster/prometheus.ex) - mnesia contrib (e.g. calculate full space occupied by a table on disk);
- [Prometheus Plugs](https://github.com/deadtrickster/prometheus-plugs) - content negotiation is turned on now. I.e. exporter should render text when request comes from browser and Protobuf when it comes from prometheus server. Format set to `:auto` by default.

I also have Slack channel (#prometheus) now: [Browser link](https://elixir-lang.slack.com/messages/prometheus).

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [March 18, 2017, 12:24pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/6 "2017-03-18T12:24:57Z")

</div>

New stuff:

- [GitHub - deadtrickster/prometheus-push: Prometheus.io pushgateway client · GitHub](https://github.com/deadtrickster/prometheus-push) - :httpc-based Pushgateway client;
- [GitHub - prometheus-erl/prometheus-httpd: Expose Prometheus metrics using inets httpd. · GitHub](https://github.com/deadtrickster/prometheus-httpd) - to expose /metrics using just httpd from inets.
- [GitHub - prometheus-erl/beam-dashboards: BEAM Prometheus Grafana · GitHub](https://github.com/deadtrickster/beam-dashboards) - Beam Grafana dashboards collection (my phoenix/plugs/ecto dashboards are coming soon. Please consider contributing yours!)

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [June 5, 2017, 10:20am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/7 "2017-06-05T10:20:44Z")

</div>

Just released new version:

- Boolean metric;
- Text format rendering optimization (\> 30% faster).

Github: [GitHub - prometheus-erl/prometheus.ex: Prometheus.io Elixir client · GitHub](https://github.com/deadtrickster/prometheus.ex)  
Hex.pm: [prometheus\_ex | Hex](https://hex.pm/packages/prometheus_ex/1.3.0)

---

<div class="post-metadata">

**Author:** ![tony612](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tony612/32/1453_2.png) [@tony612](https://forum.elixirforum.com/u/tony612)\
**Post date:** [June 5, 2017, 11:27am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/8 "2017-06-05T11:27:47Z")

</div>

Many thanks for your work. It’s very useful to have integrations with Prometheus. (Even if I haven’t used Elixir in production)

---

<div class="post-metadata">

**Author:** ![mmartinson](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mmartinson/32/5713_2.png) [@mmartinson](https://forum.elixirforum.com/u/mmartinson)\
**Post date:** [June 26, 2017, 4:11pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/9 "2017-06-26T16:11:33Z")

</div>

Thanks for your work on this. I found it pretty easy to get set up with and the docs were helpful. The pull-based model Prometheus uses is really great to get started easily sending metrics with a very small amount of overhead.

To people evaluating open source metrics solutions, would recommend based on my early experience.

---

<div class="post-metadata">

**Author:** ![MartinElvar](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/martinelvar/32/1799_2.png) [@MartinElvar](https://forum.elixirforum.com/u/MartinElvar)\
**Post date:** [September 25, 2017, 9:48am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/10 "2017-09-25T09:48:09Z")

</div>

This is really cool @deadtrickster, thank you! Are there any kind of guide i can follow, if i want to push my own metrics, which are more business oriented, like user signups etc. 🙂

---

<div class="post-metadata">

**Author:** ![orestis](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/orestis/32/1949_2.png) [@orestis](https://forum.elixirforum.com/u/orestis)\
**Post date:** [September 25, 2017, 10:31am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/11 "2017-09-25T10:31:21Z")

</div>

It’s all there in the README. For user signups, you probably want a counter. Lifting directly from the [API docs](https://hexdocs.pm/prometheus_ex/Prometheus.Metric.Counter.html), and doing some renaming:

```elixir
defmodule UserSignupInstrumenter do

  use Prometheus.Metric

  ## to be called at app/supervisor startup.
  ## to tolerate restarts use declare.
  def setup() do
    Counter.declare([name: :my_service_user_signups_total,
                     help: "User signups count.",
                     labels: [:country]])
  end

  def inc(country) do
    Counter.inc([name: : my_service_user_signups_total,
                labels: [country]])
  end

end

```

Then from the places in your code where you handle user signups:

```elixir
def handle_signup(user, other, stuff) do
  # create the user here
  country = MyGeoIPService.lookup_country(user)
  UserSignupInstrumenter.inc(country)
end

```

I made up a country label, so you can track user signups on a per-country basis. Not sure how useful it might be or not 🙂

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [September 25, 2017, 10:41am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/12 "2017-09-25T10:41:28Z")

</div>

Thanks @orestis!

User instrumenter can be rewritten in more declarative style starting from 1.4.1

```elixir
defmodule UserSignupInstrumenter do

  use Prometheus.Metric

  @counter [name: :my_service_user_signups_total,
            help: "User signups count.",
            labels: [:country]]

  def inc(country) do
    Counter.inc([name: : my_service_user_signups_total,
                labels: [country]])
  end

end

```

and `UserSignupInstrumenter __declare_prometheus_metrics__ ()` will be generated from that automatically. Found that useful when I have many metrics.

---

<div class="post-metadata">

**Author:** ![MartinElvar](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/martinelvar/32/1799_2.png) [@MartinElvar](https://forum.elixirforum.com/u/MartinElvar)\
**Post date:** [September 25, 2017, 11:28am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/13 "2017-09-25T11:28:50Z")

</div>

Cool thanks @orestis & @deadtrickster, appreciate it, gonna give it a try for our next project 😄.

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [September 25, 2017, 12:02pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/14 "2017-09-25T12:02:02Z")

</div>

And don’t hesitate joining our #prometheus channel on elixir-lang Slack team!

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [November 9, 2017, 1:53pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/15 "2017-11-09T13:53:23Z")

</div>

Starting from version 2.1 Cowboy has special metrics stream handler - [cowboy/src/cowboy\_metrics\_h.erl at master · ninenines/cowboy · GitHub](https://github.com/ninenines/cowboy/blob/master/src/cowboy_metrics_h.erl).  
[Prometheus cowboy integration](https://github.com/deadtrickster/prometheus-cowboy) uses this interface to directly instrument Cowboy now.

---

<div class="post-metadata">

**Author:** ![marat](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/m/91b2a8/32.png) [@marat](https://forum.elixirforum.com/u/marat)\
**Post date:** [July 22, 2018, 1:00pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/16 "2018-07-22T13:00:25Z")

</div>

**Q1:**  
I’m using

```elixir
      {:prometheus_ex, "~> 2.0"},
      {:prometheus_phoenix, "~> 1.2.0"},

```

and doc for [GitHub - prometheus-erl/prometheus-phoenix at v1.2.0 · GitHub](https://github.com/deadtrickster/prometheus-phoenix/tree/v1.2.0) states that it has 2 metrics:

- `phoenix_controller_call_duration_microseconds` - Whole controller pipeline execution time.
- `phoenix_controller_render_duration_microseconds` - View rendering time.

Instead, the `/metrics` page shows me

```elixir
# TYPE phoenix_controller_call_duration_microseconds histogram
# HELP phoenix_controller_call_duration_microseconds Whole controller pipeline execution time in microseconds.
# TYPE phoenix_controller_render_duration_microseconds histogram
# HELP phoenix_controller_render_duration_microseconds View rendering time in microseconds.
# TYPE phoenix_channel_receive_duration_microseconds histogram
# HELP phoenix_channel_receive_duration_microseconds Phoenix channel receive handler time in microseconds
# TYPE phoenix_channel_join_duration_microseconds histogram
# HELP phoenix_channel_join_duration_microseconds Phoenix channel join handler time in microseconds

```

Where do they come from? They have no values. After using `prometheus_phoenix 1.2.1` metrics are the same but WITH values. Where does all that come from?

**Q2:**

my config for PhoenixInstrumenter:

```elixir
config :prometheus, AppWeb.PhoenixInstrumenter,
  controller_call_labels: [:controller, :action],
  duration_buckets: [10, 25, 50, 100, 250, 500, 1000, 2500, 5000,
                     10_000, 25_000, 50_000, 100_000, 250_000, 500_000,
                     1_000_000, 2_500_000, 5_000_000, 10_000_000, 20_000_000, 30_000_000],
  registry: :default,
  duration_unit: :microseconds

```

Why the key is called `controller_call_labels`? Other sample configs have smth like

```elixir
config :prometheus, AppWeb.PipelineInstrumenter,
  labels: [:status_class, :method, :host, :scheme, :request_path],

```

but not `controller_call_labels`. How is it set?

**Q3:**  
If I add/remove values from `duration_buckets:` they change after a certain period of time. Are they cached somewhere?

Thanks ahead for the answers!

---

<div class="post-metadata">

**Author:** ![deadtrickster](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/deadtrickster/32/2294_2.png) [@deadtrickster](https://forum.elixirforum.com/u/deadtrickster)\
**Post date:** [July 22, 2018, 9:45pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/17 "2018-07-22T21:45:51Z")

</div>

Q1: probably I forgot to update the docs, new metrics are for phoenix channels  
Q2: because you can have different sets of labels for each instrumenter  
Q3: where/how you observe the chnages?

---

<div class="post-metadata">

**Author:** ![marat](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/m/91b2a8/32.png) [@marat](https://forum.elixirforum.com/u/marat)\
**Post date:** [July 23, 2018, 6:00am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/18 "2018-07-23T06:00:42Z")

</div>

@deadtrickster thank you for the answers!  
I observe the changes on the `/metrics` page. Just now I left:

```elixir
config :prometheus, AppWeb.PipelineInstrumenter,
  labels: [:status_class, :method, :host, :scheme, :request_path],
  duration_buckets: [10, 100, 1_000, 10_000, 100_000,
                     5_000_000, 10_000_000, 20_000_000, 30_000_000],

```

and the metrics still have:

```elixir
 http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="10.0"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="100.0"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="1.0e3"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="1.0e4"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="1.0e5"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="3.0e5"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="5.0e5"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="7.5e5"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="1.0e6"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="1.5e6"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="2.0e6"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="3.0e6"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="5.0e6"} 0
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="1.0e7"} 1
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="2.0e7"} 1
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="3.0e7"} 1
http_request_duration_microseconds_bucket{status_class="success",method="GET",host="localhost",scheme="http",request_path="/",le="+Inf"} 1
http_request_duration_microseconds_count{status_class="success",method="GET",host="localhost",scheme="http",request_path="/"} 1

```

Another question, **Q4** :  
I have a different Instrumenter which doesn’t get to `/metrics` page:

```elixir
defmodule AppWeb.ExampleInstrumenter do
  use Prometheus.Metric

  @histogram [name: :http_request_duration_ms,
              labels: [:method],
              buckets: [100, 300, 500, 750, 1000],
              help: "Http Request execution time"]

  def instrument(%{time: time, method: method}) do
    Histogram.observe([name: :http_request_duration_ms, labels: [method]], time)
  end
end

```

It’s included to Endpoint Instrumenters:

```elixir
config :app, AppWeb.Endpoint,
  instrumenters: [AppWeb.ExampleInstrumenter]

```

Where else should it go? The `/metrics` page doesn’t have `http_request_duration_ms` label.

Thanks again!

---

<div class="post-metadata">

**Author:** ![marat](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/m/91b2a8/32.png) [@marat](https://forum.elixirforum.com/u/marat)\
**Post date:** [July 23, 2018, 9:23am UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/19 "2018-07-23T09:23:41Z")

</div>

Hi @deadtrickster!  
The problem with `{:prometheus_phoenix, "~> 1.2.0"}` was not only that 2 metrics were missing in docs. The problem was that until I used `1.2.1` version `/metrics` page wasn’t showing any data for phoenix.

---

<div class="post-metadata">

**Author:** ![Hernan](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/858c86/32.png) [@Hernan](https://forum.elixirforum.com/u/Hernan)\
**Post date:** [February 18, 2019, 2:58pm UTC](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796/20 "2019-02-18T14:58:49Z")

</div>

Hi @deadtrickster. Thanks for all replys.  
I use your library, and i need to add label to all metrics. I need add ‘hostname’, and before the response, i set this value (in handler). My question is: exists one configuration for this?: add an label to all default\_metrics.

Thanks!,

Hernán-

[Next page](https://forum.elixirforum.com/t/prometheus-ex-prometheus-io-elixir-integrations/1796.md?page=2)
