prop/lib/microwaveprop/prom_ex.ex
Graham McIntire 71e8f53142
fix: stabilize flaky tests + silence PromEx Oban poller in test
- HrrrClient idx-cache test only invalidated the surface idx URL, but
  fetch_profile also fetches a pressure idx. Previous runs' state for
  the pressure key decided whether the counter landed at 1 (prior run
  cached it, pass) or 2 (cold, fail). Invalidate both + assert 2 total
  fetches to reflect the actual code path.
- CsvImportTest deadlocked against other async DataCase tests when
  inline Oban child jobs upserted iemre_observations/terrain_profiles
  with a shared conflict target. Flip to async: false — same fix as
  ContactWeatherEnqueueWorkerTest earlier this session.
- PromEx.Plugins.Oban runs a 5s telemetry_poller that queries the DB,
  but its poller PID has no sandbox connection in test and crashed
  with DBConnection.OwnershipError on every tick, spamming the log.
  Gate the plugin on a config flag and skip it in config/test.exs;
  prod behaviour unchanged.
2026-04-21 13:49:07 -05:00

53 lines
1.7 KiB
Elixir

defmodule Microwaveprop.PromEx do
@moduledoc """
Prometheus metrics exporter. Combines PromEx's built-in plugins for
Application/BEAM/Phoenix/Ecto/Oban with our own custom metrics
(Microwaveprop.Instrument spans, Oban queue-depth gauges).
A dedicated Prometheus server outside the Kubernetes cluster scrapes
`/metrics` over the app's normal HTTP endpoint. The `MicrowavepropWeb.Router`
is responsible for making that route reachable.
"""
use PromEx, otp_app: :microwaveprop
alias PromEx.Plugins
@impl true
def plugins do
# Oban plugin's queue-depth metric is a telemetry_poller that runs
# an Ecto query every 5 s; in the test env that poller has no
# sandbox connection and crashes with DBConnection.OwnershipError,
# so it's skipped there.
oban_plugin =
if Application.get_env(:microwaveprop, :prom_ex_include_oban_plugin, true),
do: [Plugins.Oban],
else: []
[
# Defaults: VM memory, process counts, scheduler util, app version.
Plugins.Application,
Plugins.Beam,
# Phoenix: request duration by route/status, channel/socket events.
{Plugins.Phoenix, router: MicrowavepropWeb.Router, endpoint: MicrowavepropWeb.Endpoint},
# Ecto: query duration, queue time, pool size.
{Plugins.Ecto, otp_app: :microwaveprop, repos: [Microwaveprop.Repo]},
# Our own spans: Instrument.span/3 emits [:microwaveprop | suffix]
# events; this plugin converts them to Prometheus histograms.
Microwaveprop.PromEx.InstrumentPlugin
] ++ oban_plugin
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"}
]
end
end