- 
                Notifications
    You must be signed in to change notification settings 
- Fork 356
Cookbook: Prometheus integration
        Mike R edited this page Aug 9, 2019 
        ·
        4 revisions
      
    Because prometheus.erl requires declaring metrics before using them you need to call Tesla.Middleware.Prometheus.setup() before your application starts.
Requires {:prometheus, "~> 4.0"} dependency.
defmodule Tesla.Middleware.Prometheus do
  @moduledoc """
  Prometheus metrics
  Usage:
      defmodule MyApi do
        use Tesla
        plug Tesla.Middleware.Prometheus
      end
      # lib/my_app/application.ex
      defmodule MyApp.Application do
        def start(_type, _args) do
          Tesla.Middleware.Prometheus.setup()
          # ...
        end
      end
  Metrics:
    - tesla_request_duration_seconds{host,status}
  """
  @buckets [
    0.001,
    0.002,
    0.004,
    0.008,
    0.016,
    0.032,
    0.064,
    0.128,
    0.256,
    0.512,
    1.024,
    2.048,
    4.096
  ]
  def setup do
    :prometheus_histogram.declare(
      name: :tesla_request_duration_seconds,
      help: "Time spent executing the request",
      labels: [:host, :status],
      buckets: @buckets
    )
  end
  def call(env, next, _opts) do
    start = System.monotonic_time()
    response = Tesla.run(env, next)
    stop = System.monotonic_time()
    labels = [
      URI.parse(env.url).host,
      status(response)
    ]
    :prometheus_histogram.observe(:tesla_request_duration_seconds, labels, stop - start)
    response
  end
  defp status({:ok, %{status: status}}), do: status
  defp status(_error), do: "error"
end