Our blog

Know what we are thinking and doing

July 09, 2019 / by / 4 comments

Exposing Elixir application metrics using Prometheus

Overview

Exposing Elixir application metrics using Prometheus is pretty simple really - you use a dependency which exposes a HTTP(S) endpoint or write your own.

Prometheus discovers which nodes are exposing this endpoint by means of kubernetes pod annotations (Prometheus itself is typically installed using helm or you can do it manually).

Prometheus polls a HTTP(S) endpoint - it is not idiomatic to push metrics to Prometheus.

Here’s a reasonable architectural overview - Production grade Kubernetes Monitoring using Prometheus

Config in a demo project

The Instrumenter

defmodule IsItUp.Metrics.Instrumenter do
  use Prometheus.Metric
  alias Prometheus.Metric.{Counter, Histogram, Gauge}
  require Logger

The Exporter

defmodule IsItUp.Metrics.PlugExporter do
  use Prometheus.PlugExporter
end

Initialization at Application startup :

require Prometheus.Registry
Prometheus.Registry.register_collector(:prometheus_process_collector)
IsItUp.Metrics.PlugExporter.setup()

Adding to the plug Pipeline

plug(IsItUp.Metrics.PlugExporter, %{})

The path, ‘/metrics’ is created by the prometheus_plugs dependency :

/metrics - check the status of google.co.uk

And the application dependencies to make all this happen ?

{:plug_cowboy, "~> 2.1.0"},
{:prometheus_ex, "~> 3.0"},
{:prometheus_plugs, "~> 1.1.5"},
{:prometheus_process_collector, "~> 1.4"},

UML diagrams

Setup sequence

sequenceDiagram Instrumenter -->> Prometheus : declares custom metrics SomeModule -->> Instrumenter : Instrumenter.http_check(host) Instrumenter -->> Prometheus : Gauge.set(number)

Deployment diagram

graph LR Module -- generates metrics --> PrometheusEndpoint Prometheus -- scrapes --> PrometheusEndpoint(Round Rect) Grafana -- queries --> Prometheus User -- views --> Grafana
<-- discus block rendered -->