diff --git a/config/config.exs b/config/config.exs index 7df3a77..94282c4 100644 --- a/config/config.exs +++ b/config/config.exs @@ -99,6 +99,20 @@ config :logger, :default_formatter, # Use Jason for JSON parsing in Phoenix config :phoenix, :json_library, Jason +config :pinchflat, Pinchflat.PromEx, + disabled: false, + manual_metrics_start_delay: :no_delay, + drop_metrics_groups: [], + metrics_server: :disabled, + grafana: [ + host: System.get_env("GRAFANA_CLOUD_URL", "http://192.168.1.170:3033"), + username: System.get_env("GRAFANA_USERNAME", "admin"), + password: System.get_env("GRAFANA_PASSWORD", "admin"), + # This is an optional setting and will default to `true` + folder_name: "zero-to-graphql-using-elixir", + upload_dashboards_on_start: true + ] + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{config_env()}.exs" diff --git a/lib/pinchflat/application.ex b/lib/pinchflat/application.ex index 61b2538..969f2cb 100644 --- a/lib/pinchflat/application.ex +++ b/lib/pinchflat/application.ex @@ -11,6 +11,7 @@ defmodule Pinchflat.Application do check_and_update_timezone() children = [ + Pinchflat.PromEx, PinchflatWeb.Telemetry, Pinchflat.Repo, # Must be before startup tasks diff --git a/lib/pinchflat/prom_ex.ex b/lib/pinchflat/prom_ex.ex new file mode 100644 index 0000000..2dd65a4 --- /dev/null +++ b/lib/pinchflat/prom_ex.ex @@ -0,0 +1,90 @@ +defmodule Pinchflat.PromEx do + @moduledoc """ + Be sure to add the following to finish setting up PromEx: + + 1. Update your configuration (config.exs, dev.exs, prod.exs, releases.exs, etc) to + configure the necessary bit of PromEx. Be sure to check out `PromEx.Config` for + more details regarding configuring PromEx: + ``` + config :pinchflat, Pinchflat.PromEx, + disabled: false, + manual_metrics_start_delay: :no_delay, + drop_metrics_groups: [], + grafana: :disabled, + metrics_server: :disabled + ``` + + 2. Add this module to your application supervision tree. It should be one of the first + things that is started so that no Telemetry events are missed. For example, if PromEx + is started after your Repo module, you will miss Ecto's init events and the dashboards + will be missing some data points: + ``` + def start(_type, _args) do + children = [ + Pinchflat.PromEx, + + ... + ] + + ... + end + ``` + + 3. Update your `endpoint.ex` file to expose your metrics (or configure a standalone + server using the `:metrics_server` config options). Be sure to put this plug before + your `Plug.Telemetry` entry so that you can avoid having calls to your `/metrics` + endpoint create their own metrics and logs which can pollute your logs/metrics given + that Prometheus will scrape at a regular interval and that can get noisy: + ``` + defmodule PinchflatWeb.Endpoint do + use Phoenix.Endpoint, otp_app: :pinchflat + + ... + + plug PromEx.Plug, prom_ex_module: Pinchflat.PromEx + + ... + end + ``` + + 4. Update the list of plugins in the `plugins/0` function return list to reflect your + application's dependencies. Also update the list of dashboards that are to be uploaded + to Grafana in the `dashboards/0` function. + """ + + use PromEx, otp_app: :pinchflat + + alias PromEx.Plugins + + @impl true + def plugins do + [ + Plugins.Application, + Plugins.Beam, + {Plugins.Phoenix, router: PinchflatWeb.Router, endpoint: PinchflatWeb.Endpoint}, + Plugins.Ecto, + Plugins.Oban, + Plugins.PhoenixLiveView + ] + end + + @impl true + def dashboard_assigns do + [ + datasource_id: "prometheus", + default_selected_interval: "30s" + ] + end + + @impl true + def dashboards do + [ + {:prom_ex, "application.json"}, + {:prom_ex, "beam.json"}, + {:prom_ex, "phoenix.json"}, + {:prom_ex, "ecto.json"}, + {:prom_ex, "oban.json"}, + {:prom_ex, "phoenix_live_view.json"} + ] + end +end diff --git a/lib/pinchflat_web/endpoint.ex b/lib/pinchflat_web/endpoint.ex index 66ee1b6..b93b36e 100644 --- a/lib/pinchflat_web/endpoint.ex +++ b/lib/pinchflat_web/endpoint.ex @@ -32,6 +32,8 @@ defmodule PinchflatWeb.Endpoint do plug Phoenix.Ecto.CheckRepoStatus, otp_app: :pinchflat end + plug PromEx.Plug, prom_ex_module: Pinchflat.PromEx + plug Phoenix.LiveDashboard.RequestLogger, param_key: "request_logger", cookie_key: "request_logger"