# `PromEx`
[🔗](https://github.com/akoutmos/prom_ex/blob/master/lib/prom_ex.ex#L1)

PromEx is a plugin based library which can be used to capture
telemetry events and report them out for consumption by Prometheus.
The main purpose of this particular library is to provide the
behaviour that all PromEx plugins leverage so that a consistent
interface can be achieved and so that leveraging multiple plugins is
effortless from the user's point of view.

To use PromEx you need to define a module that uses the PromEx library. This module
will also need to have some application config set for it similarly to how Ecto does.
For example, for a PromEx module defined like so:

```elixir
defmodule MyApp.PromEx do
  use PromEx,  otp_app: :web_app

  ...
end
```

You would have an application configuration set like so:

```elixir
config :my_app, MyApp.PromEx,
  manual_metrics_start_delay: :no_delay,
  drop_metrics_groups: [],
  grafana: [
    host: System.get_env("GRAFANA_HOST", "http://grafana:3000"),
    auth_token: System.get_env("GRAFANA_TOKEN", ""),
    upload_dashboards_on_start: true,
    folder_name: "My App Dashboards",
    annotate_app_lifecycle: true
  ]
```

The options that you can pass to PromEx macro are outlined in the following section. In order
to tell PromEx what plugins you would like to use and what dashboards you would like PromEx
to upload for you, implement the `plugins/0` and `dashboards/0` callbacks respectively. The
`dashboard_assigns/0` callback will be used when your EEx template Grafana dashboards are
rendered so that the dashboards that are created for your application coincide with the PromEx
configuration for the application. If your dashboards are not EEx templates, then the dashboard
assigns are not passed through. Each plugin also has an accompanying Grafana dashboard that you
can leverage to plot all of the plugin captured data.

In order to expose captured metrics, you can leverage the PromEx provided Plug `PromEx.Plug`.
See the `PromEx.Plug` documentation modules for specifics on how to use it.

## Options

* `:otp_app` - This is a REQUIRED field and is used by PromEx to fetch the application
  configuration values for the various PromEx capture modules. Make sure that this value
  matches the `:app` value in `project/0` from your `mix.exs` file. If you use the PromEx
  `mix prom_ex.create` mix task this will be done automatically for you.

## Top level PromEx Configuration

PromEx is generally configured per application per PromEx module as you saw in the previous section. The only
setting that is currently available globally for all instances of PromEx is that of the storage adapter. The
storage adapter configuration determines how PromEx captures and stores metrics. There are currently two
available adapters:

1. [TelemetryMetricsPrometheus.Core](https://github.com/beam-telemetry/telemetry_metrics_prometheus_core) - This is the
default adapter and is included with PromEx.
2. [Peep](https://github.com/rkallos/peep) - In order to use Peep as your storage adapter,  you will need to add the following
to your `config.exs` file:

    ```elixir
    config :prom_ex, :storage_adapter, PromEx.Storage.Peep
    ```

## PromEx Plugins

All metrics collection will be delegated to plugins which can be found here:

Foundational metrics:
  - [X] `PromEx.Plugins.Application` Application related informational metrics
  - [X] `PromEx.Plugins.Beam` BEAM virtual machine metrics
  - [ ] Operating System (http://erlang.org/doc/man/os_mon_app.html)

Library metrics:
  - [X] `PromEx.Plugins.Ecto` - [Telemetry docs](https://hexdocs.pm/ecto/Ecto.Repo.html#module-telemetry-events)
  - [X] `PromEx.Plugins.Oban` - [Telemetry docs](https://hexdocs.pm/oban/Oban.Telemetry.html)
  - [X] `PromEx.Plugins.Phoenix` - [Telemetry docs](https://hexdocs.pm/phoenix/Phoenix.Logger.html)
  - [X] `PromEx.Plugins.PhoenixLiveView` - [Telemetry docs](https://hexdocs.pm/phoenix_live_view/telemetry.html)
  - [X] `PromEx.Plugins.Absinthe` - [Telemetry docs](https://hexdocs.pm/absinthe/1.5.3/telemetry.html)
  - [X] `PromEx.Plugins.PlugCowboy` - [Telemetry docs](https://hexdocs.pm/plug_cowboy/2.4.0/Plug.Cowboy.html#module-instrumentation)
  - [X] `PromEx.Plugins.PlugRouter` - [Telemetry docs](https://hexdocs.pm/plug/1.12.1/Plug.Router.html#module-telemetry)
  - [X] `PromEx.Plugins.Broadway` - [Telemetry docs](https://hexdocs.pm/broadway/Broadway.html#module-telemetry)

Backlog Elixir library metrics:
  - [ ] Finch - [Telemetry docs](https://hexdocs.pm/finch/Finch.Telemetry.html#content)
  - [ ] Swoosh - [Telemetry docs](https://hexdocs.pm/swoosh/1.5.0/Swoosh.html#module-telemetry)
  - [ ] ChromicPDF - [Telemetry docs](https://hexdocs.pm/chromic_pdf/ChromicPDF.html#module-telemetry-support)
  - [ ] Dataloader - [Telemetry docs](https://hexdocs.pm/dataloader/telemetry.html)
  - [ ] GenRMQ - [Telemetry docs](https://hexdocs.pm/gen_rmq/3.0.0/GenRMQ.Publisher.Telemetry.html and https://hexdocs.pm/gen_rmq/3.0.0/GenRMQ.Consumer.Telemetry.html)
  - [ ] Plug - [Telemetry docs](https://hexdocs.pm/plug/Plug.Telemetry.html)
  - [ ] Redix - [Telemetry docs](https://hexdocs.pm/redix/Redix.Telemetry.html)
  - [ ] Tesla - [Telemetry docs](https://hexdocs.pm/tesla/Tesla.Middleware.Telemetry.html)
  - [ ] Memcachex - [Telemetry docs](https://hexdocs.pm/memcachex/0.5.0/Memcache.html#module-telemetry)
  - [ ] Nebulex - [Telemetry docs](https://hexdocs.pm/nebulex/2.0.0-rc.0/telemetry.html)
  - [ ] Horde - [Telemetry docs](https://github.com/derekkraan/horde/blob/master/lib/horde/supervisor_telemetry_poller.ex)
  - [ ] Cachex - (Need to open up PR)
  - [ ] Quantum - [Telemetry docs](https://hexdocs.pm/quantum/3.3.0/telemetry.html#content)
  - [ ] ETS - [Erlang docs](https://www.erlang.org/doc/man/ets.html#info-1)

Database cron based metrics:
  - [ ] Postgres (https://github.com/pawurb/ecto_psql_extras for inspiration)
  - [ ] Mnesia (https://github.com/deadtrickster/prometheus.erl/blob/master/src/collectors/mnesia/prometheus_mnesia_collector.erl for inspiration)
  - [ ] MySQL (https://github.com/prometheus/mysqld_exporter for inspiration)
  - [ ] Redis (https://github.com/oliver006/redis_exporter for inspiration)
  - [ ] MongoDB (https://github.com/percona/mongodb_exporter for inspiration)

# `dashboard_definition`

```elixir
@type dashboard_definition() ::
  {atom(), String.t()} | {atom(), String.t(), keyword(String.t())}
```

# `measurements_mfa`

```elixir
@type measurements_mfa() :: {module(), atom(), list()}
```

# `plugin_definition`

```elixir
@type plugin_definition() :: module() | {module(), keyword()}
```

# `telemetry_metrics`

```elixir
@type telemetry_metrics() ::
  Telemetry.Metrics.Counter.t()
  | Telemetry.Metrics.Distribution.t()
  | Telemetry.Metrics.LastValue.t()
  | Telemetry.Metrics.Sum.t()
  | Telemetry.Metrics.Summary.t()
```

# `dashboard_assigns`

```elixir
@callback dashboard_assigns() :: keyword()
```

# `dashboards`

```elixir
@callback dashboards() :: [dashboard_definition()]
```

# `init_opts`

```elixir
@callback init_opts() :: PromEx.Config.t()
```

# `plugins`

```elixir
@callback plugins() :: [plugin_definition()]
```

# `get_metrics`

```elixir
@spec get_metrics(prom_ex_module :: module()) :: String.t() | :prom_ex_down
```

A simple pass-through to fetch all of the currently configured metrics. This is
primarily used by the exporter plug to fetch all of the metrics so that they
can be scraped.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
