prometheus_ecto v1.4.3 Prometheus.EctoInstrumenter View Source

Ecto instrumenter generator for Prometheus. Implemented as Ecto logger.

Usage

  1. Define your instrumenter:
defmodule MyApp.Repo.Instrumenter do
  use Prometheus.EctoInstrumenter
end
  1. Call MyApp.Repo.Instrumenter.setup/0 when application starts (e.g. supervisor setup):
MyApp.Repo.Instrumenter.setup()
  1. Add MyApp.Repo.Instrumenter to Repo loggers list:
config :myapp, MyApp.Repo,
  ...
  loggers: [MyApp.Repo.Instrumenter, Ecto.LogEntry]
  ...

Metrics

Each Ecto query has different stages. Currently there are three of them:

  • queue - when socket checked out from the pool;
  • query (this instrumenter uses db_query name) - when actual database query performed;
  • decode - when query result decoded.

Any of these stages can be nil (i.e. not performed). For example queries inside transaction won’t have queue stage or query can be cashed, etc.

You can instrument these stages separately

  • queue - ecto_queue_duration_<duration_unit>
  • query - ecto_db_query_duration_<duration_unit>
  • decode - ecto_decode_duration_<duration_unit>.

Stages can be disabled/enabled via configuration. By default all stages are enabled.

There is also ecto_query_duration_<duration_unit> metric that observers total query execution time. Basically it sums non-nil stages.

There’s an ability to count total amount of Ecto queries. It is disabled by default, to enable set counter: true in configuration for your instrumenter module then you can instrument it via ecto_queries_total.

Default labels:

  • :result

Configuration

Instrumenter configured via :prometheus application environment MyApp.Repo.Instrumenter key (i.e. app env key is the name of the instrumenter).

Default configuration:

config :prometheus, MyApp.Repo.Instrumenter,
  stages: [:queue, :query, :decode],
  counter: false,
  labels: [:result],
  query_duration_buckets: [10, 100, 1_000, 10_000, 100_000, 300_000,
                           500_000, 750_000, 1_000_000, 1_500_000,
                           2_000_000, 3_000_000],
  registry: :default,
  duration_unit: :microseconds

Available duration units:

  • microseconds;
  • milliseconds;
  • seconds;
  • minutes;
  • hours;
  • days.

Bear in mind that buckets are so if you are not using default unit you also have to override buckets.

Custom Labels

Custom labels can be defined by implementing label_value/2 function in instrumenter directly or by calling exported function from other module.

  labels: [:result,
           :my_private_label,
           {:label_from_other_module, Module}, # eqv to {Module, label_value}
           {:non_default_label_value, {Module, custom_fun}}]


defmodule MyApp.Repo.Instrumenter do
  use Prometheus.EctoInstrumenter

  label_value(:my_private_label, log_entry) do
    ...
  end
end