neiam
/apollos_crib
It's Apollo's Crib
public · Issues · Pulls 1 · Labels · Forks · Compare · Actions failure · Badges · Packages
⭐
Log in to mark this repository.
Serve Prometheus metrics for the whole release on 9568
fb200bd · Gabriel Morell · 2026-08-24 03:31
Message
{commit_body(@commit)}
Files changed
modified
apps/room_hermes/mix.exs
+5
−1
@@ -49,7 +49,11 @@ defmodule RoomHermes.MixProject do
| 49 | 49 | {:floki, ">= 0.30.0", only: :test}, |
| 50 | 50 | {:phoenix_live_dashboard, "~> 0.8.3"}, |
| 51 | 51 | {:esbuild, "~> 0.3", runtime: Mix.env() == :dev}, |
| 52 | − {:telemetry_metrics, "~> 0.6"}, | |
| 52 | + # 1.0 rather than 0.6 because PromEx requires it (see | |
| 53 | + # apps/room_observatory). The 1.0 release was a stability | |
| 54 | + # declaration rather than a rewrite — counter/1, summary/1, | |
| 55 | + # last_value/1 and distribution/1 are unchanged. | |
| 56 | + {:telemetry_metrics, "~> 1.0"}, | |
| 53 | 57 | {:telemetry_poller, "~> 1.0"}, |
| 54 | 58 | {:gettext, "~> 0.18"}, |
| 55 | 59 | {:jason, "~> 1.2"}, |
added
apps/room_observatory/lib/room_observatory.ex
+7
−0
@@ -0,0 +1,7 @@
| 1 | +defmodule RoomObservatory do | |
| 2 | + @moduledoc """ | |
| 3 | + Prometheus metrics for the apollos-crib release. | |
| 4 | + | |
| 5 | + There is no domain logic here. See `RoomObservatory.PromEx`. | |
| 6 | + """ | |
| 7 | +end |
added
apps/room_observatory/lib/room_observatory/application.ex
+20
−0
@@ -0,0 +1,20 @@
| 1 | +defmodule RoomObservatory.Application do | |
| 2 | + @moduledoc false | |
| 3 | + | |
| 4 | + use Application | |
| 5 | + | |
| 6 | + @impl true | |
| 7 | + def start(_type, _args) do | |
| 8 | + # PromEx is the whole application. It starts its own metrics server on | |
| 9 | + # 9568 (see config/config.exs), so there is nothing else to supervise. | |
| 10 | + # | |
| 11 | + # Both Phoenix endpoints are already running by the time this starts — | |
| 12 | + # room_sanctum and room_hermes come earlier in the release's application | |
| 13 | + # list, because this app depends on both. That ordering does not matter for | |
| 14 | + # correctness: PromEx attaches :telemetry handlers, and a handler attached | |
| 15 | + # after an endpoint has started still receives every subsequent request. | |
| 16 | + children = [RoomObservatory.PromEx] | |
| 17 | + | |
| 18 | + Supervisor.start_link(children, strategy: :one_for_one, name: RoomObservatory.Supervisor) | |
| 19 | + end | |
| 20 | +end |
added
apps/room_observatory/lib/room_observatory/prom_ex.ex
+78
−0
@@ -0,0 +1,78 @@
| 1 | +defmodule RoomObservatory.PromEx do | |
| 2 | + @moduledoc """ | |
| 3 | + One PromEx instance covering the whole apollos-crib release. | |
| 4 | + | |
| 5 | + ## Why one, and why it lives in its own app | |
| 6 | + | |
| 7 | + The release runs both Phoenix apps in a single BEAM node. Two PromEx modules | |
| 8 | + would mean two metric stores, two `/metrics` endpoints and two sets of BEAM | |
| 9 | + gauges describing the *same* VM — and a pod carries only one | |
| 10 | + `prometheus.io/port` annotation, so one of them would go unscraped. | |
| 11 | + | |
| 12 | + So it is one module naming both endpoints, both routers and both repos. That | |
| 13 | + requires an app that depends on both, which neither Phoenix app does or | |
| 14 | + should — hence `room_observatory`. | |
| 15 | + | |
| 16 | + ## Why the prefix is `phx` | |
| 17 | + | |
| 18 | + PromEx names metrics `[otp_app, :prom_ex, plugin]` by default, which here | |
| 19 | + would be `room_observatory_prom_ex_phoenix_*` — a name describing the | |
| 20 | + observability app rather than anything anyone wants to graph, and different | |
| 21 | + again from the six standalone Phoenix apps in this fleet. | |
| 22 | + | |
| 23 | + Every plugin below overrides that to `[:phx, plugin]`, matching angler, | |
| 24 | + feedpug, git-gud, neiam-ircd, waxx and camerite exactly. The Kubernetes | |
| 25 | + `namespace` label is what separates them, so one dashboard shape describes | |
| 26 | + all seven. | |
| 27 | + | |
| 28 | + ## The two endpoints are not separated by label | |
| 29 | + | |
| 30 | + Worth knowing before reading a panel here, because it is easy to assume | |
| 31 | + otherwise: PromEx's HTTP metrics are tagged | |
| 32 | + `{status, method, path, controller, action, host}` and that list is hardcoded | |
| 33 | + in the plugin. There is **no `endpoint` label**, so room_sanctum's and | |
| 34 | + room_hermes's requests land in the same `phx_phoenix_http_requests_total` | |
| 35 | + series set and a naive `sum` covers both. | |
| 36 | + | |
| 37 | + What separates them in practice is `host`: sanctum is behind the Ingress at | |
| 38 | + `ac.neiam.org`, while hermes has a Service and no Ingress, so it is only | |
| 39 | + reached in-cluster under a different Host header. That is a property of the | |
| 40 | + deployment rather than of the instrumentation, and it stops being true the | |
| 41 | + moment hermes gets an Ingress of its own. | |
| 42 | + | |
| 43 | + The channel, socket and `endpoint_info` metrics *do* carry an `endpoint` | |
| 44 | + label. Only the HTTP ones do not. | |
| 45 | + | |
| 46 | + ## Grafana upload is off | |
| 47 | + | |
| 48 | + PromEx can push its own dashboards to Grafana on boot. The dashboards for | |
| 49 | + this fleet are committed in `deployment/grafana` and pushed from there, so an | |
| 50 | + uploaded one would either be reverted by the next sync or quietly win over | |
| 51 | + the committed file. Disabled explicitly in `config/config.exs`. | |
| 52 | + """ | |
| 53 | + | |
| 54 | + use PromEx, otp_app: :room_observatory | |
| 55 | + | |
| 56 | + alias PromEx.Plugins | |
| 57 | + | |
| 58 | + @impl true | |
| 59 | + def plugins do | |
| 60 | + [ | |
| 61 | + {Plugins.Application, metric_prefix: [:phx, :application]}, | |
| 62 | + # One VM, so exactly one source of BEAM metrics. This is the plugin that | |
| 63 | + # would have double-counted had this been two PromEx modules. | |
| 64 | + {Plugins.Beam, metric_prefix: [:phx, :beam]}, | |
| 65 | + {Plugins.Phoenix, | |
| 66 | + endpoints: [ | |
| 67 | + {RoomSanctumWeb.Endpoint, routers: [RoomSanctumWeb.Router]}, | |
| 68 | + {RoomHermesWeb.Endpoint, routers: [RoomHermesWeb.Router]} | |
| 69 | + ], | |
| 70 | + metric_prefix: [:phx, :phoenix]}, | |
| 71 | + # Both repos report under the same metric names, separated by the `repo` | |
| 72 | + # label the Ecto plugin already attaches. | |
| 73 | + {Plugins.Ecto, repos: [RoomSanctum.Repo, RoomHermes.Repo], metric_prefix: [:phx, :ecto]}, | |
| 74 | + # Oban runs under room_sanctum only (see config/config.exs). | |
| 75 | + {Plugins.Oban, metric_prefix: [:phx, :oban]} | |
| 76 | + ] | |
| 77 | + end | |
| 78 | +end |
added
apps/room_observatory/mix.exs
+45
−0
@@ -0,0 +1,45 @@
| 1 | +defmodule RoomObservatory.MixProject do | |
| 2 | + use Mix.Project | |
| 3 | + | |
| 4 | + def project do | |
| 5 | + [ | |
| 6 | + app: :room_observatory, | |
| 7 | + version: "0.1.0", | |
| 8 | + build_path: "../../_build", | |
| 9 | + config_path: "../../config/config.exs", | |
| 10 | + deps_path: "../../deps", | |
| 11 | + lockfile: "../../mix.lock", | |
| 12 | + elixir: "~> 1.12", | |
| 13 | + start_permanent: Mix.env() == :prod, | |
| 14 | + deps: deps() | |
| 15 | + ] | |
| 16 | + end | |
| 17 | + | |
| 18 | + def application do | |
| 19 | + [ | |
| 20 | + mod: {RoomObservatory.Application, []}, | |
| 21 | + extra_applications: [:logger] | |
| 22 | + ] | |
| 23 | + end | |
| 24 | + | |
| 25 | + # This app exists for one reason: something has to know about *both* Phoenix | |
| 26 | + # apps at once. | |
| 27 | + # | |
| 28 | + # room_sanctum and room_hermes do not depend on each other and should not | |
| 29 | + # start to. But they run in one release, in one BEAM, and a single PromEx | |
| 30 | + # module has to name both routers and both repos — so the alternative was | |
| 31 | + # making one of them depend on the other purely for metrics, which would be a | |
| 32 | + # lie about the architecture that outlives whoever wrote it. | |
| 33 | + defp deps do | |
| 34 | + [ | |
| 35 | + {:prom_ex, "~> 1.11.0"}, | |
| 36 | + # PromEx's own metrics_server is Plug.Cowboy-based. That is the right | |
| 37 | + # choice *here* — unlike the Bandit-based apps in this fleet, cowboy is | |
| 38 | + # already in this release via Phoenix 1.7 — so it is declared rather than | |
| 39 | + # leaned on transitively. | |
| 40 | + {:plug_cowboy, "~> 2.5"}, | |
| 41 | + {:room_sanctum, in_umbrella: true}, | |
| 42 | + {:room_hermes, in_umbrella: true} | |
| 43 | + ] | |
| 44 | + end | |
| 45 | +end |
modified
apps/room_sanctum/mix.exs
+5
−1
@@ -60,7 +60,11 @@ defmodule RoomSanctum.MixProject do
| 60 | 60 | {:phoenix_live_dashboard, "~> 0.8.3"}, |
| 61 | 61 | {:esbuild, "~> 0.7", runtime: Mix.env() == :dev}, |
| 62 | 62 | {:swoosh, "~> 1.3"}, |
| 63 | − {:telemetry_metrics, "~> 0.6"}, | |
| 63 | + # 1.0 rather than 0.6 because PromEx requires it (see | |
| 64 | + # apps/room_observatory). The 1.0 release was a stability | |
| 65 | + # declaration rather than a rewrite — counter/1, summary/1, | |
| 66 | + # last_value/1 and distribution/1 are unchanged. | |
| 67 | + {:telemetry_metrics, "~> 1.0"}, | |
| 64 | 68 | {:telemetry_poller, "~> 1.0"}, |
| 65 | 69 | {:gettext, "~> 0.18"}, |
| 66 | 70 | {:jason, "~> 1.2"}, |
modified
config/config.exs
+21
−0
@@ -127,6 +127,27 @@ config :phoenix, :template_engines, [
| 127 | 127 | neex: LiveViewNative.Engine |
| 128 | 128 | ] |
| 129 | 129 | |
| 130 | +# Prometheus metrics for the whole release — see apps/room_observatory. | |
| 131 | +# | |
| 132 | +# `metrics_server` rather than a plug in either endpoint: /metrics on a Phoenix | |
| 133 | +# router would be reachable through the Ingress, which matches `/` as a prefix. | |
| 134 | +# PromEx's server is Plug.Cowboy-based, which is the right fit here because | |
| 135 | +# this release already runs cowboy via Phoenix 1.7 — the Bandit apps in this | |
| 136 | +# fleet use a second Bandit listener instead, for the same reason in reverse. | |
| 137 | +# | |
| 138 | +# `grafana: :disabled` is load-bearing, not boilerplate: PromEx would otherwise | |
| 139 | +# upload its own dashboards on boot, and this fleet's dashboards are committed | |
| 140 | +# in deployment/grafana and pushed from there. | |
| 141 | +config :room_observatory, RoomObservatory.PromEx, | |
| 142 | + disabled: false, | |
| 143 | + manual_metrics_start_delay: :no_delay, | |
| 144 | + drop_metrics_groups: [], | |
| 145 | + grafana: :disabled, | |
| 146 | + metrics_server: [ | |
| 147 | + port: 9568, | |
| 148 | + path: "/metrics" | |
| 149 | + ] | |
| 150 | + | |
| 130 | 151 | # Import environment specific config. This must remain at the bottom |
| 131 | 152 | # of this file so it overrides the configuration defined above. |
| 132 | 153 | import_config "#{config_env()}.exs" |
modified
mix.exs
+2
−0
@@ -12,6 +12,8 @@ defmodule ApollosCrib.MixProject do
| 12 | 12 | include_erts: true, |
| 13 | 13 | include_executables_for: [:unix], |
| 14 | 14 | applications: [ |
| 15 | + # Depends on both Phoenix apps, so OTP starts it after them. | |
| 16 | + room_observatory: :permanent, | |
| 15 | 17 | room_sanctum: :permanent, |
| 16 | 18 | room_hermes: :permanent, |
| 17 | 19 | room_zeus: :permanent, |
modified
mix.lock
+9
−1
@@ -22,6 +22,7 @@
| 22 | 22 | "esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"}, |
| 23 | 23 | "expo": {:hex, :expo, "1.1.0", "f7b9ed7fb5745ebe1eeedf3d6f29226c5dd52897ac67c0f8af62a07e661e5c75", [:mix], [], "hexpm", "fbadf93f4700fb44c331362177bdca9eeb8097e8b0ef525c9cc501cb9917c960"}, |
| 24 | 24 | "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, |
| 25 | + "finch": {:hex, :finch, "0.23.0", "e3f9287ac25a8832f848b144c2b57346aac65b205e2e0629a52adfe6507fd837", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.8", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "80e58d3f936f57e3fdf404f83a3642897ae6d9fb642934e46da4d8fe761b99d5"}, | |
| 25 | 26 | "floki": {:hex, :floki, "0.38.4", "10f98971e892aed2c2f1b3a0f928e488e3797e1c6dd3dfd98db40b14e9a78bcf", [:mix], [], "hexpm", "bdb34645eee8e79845c7edaca2d4099a52804ee4d4a3ecc683a69451f0244973"}, |
| 26 | 27 | "friendlyid": {:hex, :friendlyid, "0.2.0", "915632436ac2e5abd396b7642db8b92773036a50d4747e2ce68b988d130f85de", [:mix], [], "hexpm", "2ead5268d6f3daf3eae4965fa669783aaca073da2bbed05f449866535b099ec9"}, |
| 27 | 28 | "gen_smtp": {:hex, :gen_smtp, "1.3.0", "62c3d91f0dcf6ce9db71bcb6881d7ad0d1d834c7f38c13fa8e952f4104a8442e", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "0b73fbf069864ecbce02fe653b16d3f35fd889d0fdd4e14527675565c39d84e6"}, |
@@ -30,6 +31,7 @@
| 30 | 31 | "gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"}, |
| 31 | 32 | "hackney": {:hex, :hackney, "1.25.0", "390e9b83f31e5b325b9f43b76e1a785cbdb69b5b6cd4e079aa67835ded046867", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "7209bfd75fd1f42467211ff8f59ea74d6f2a9e81cbcee95a56711ee79fd6b1d4"}, |
| 32 | 33 | "healthchex": {:hex, :healthchex, "0.2.1", "e4e36631aef94075879946f31fc328d5466b127aaf434746320332a1d7db5871", [:mix], [{:plug_cowboy, "~> 2.4", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm", "eb7dfb8f8606e742c73b8bf4053968e48fba38ae8b37fec214fe09c40800b93f"}, |
| 34 | + "hpax": {:hex, :hpax, "1.0.4", "777de5d433b0fbdc7c418159c8055910faa8047ffdb3d6b31098d2a46cd7685c", [:mix], [], "hexpm", "afc7cb142ebcc2d01ce7816190b98ce5dd49e799111b24249f3443d730f377ca"}, | |
| 33 | 35 | "httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"}, |
| 34 | 36 | "icalendar": {:hex, :icalendar, "1.1.2", "5d0afff5d0143c5bd43f18ae32a777bf0fb9a724543ab05229a460d368f0a5e7", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "2060f8e353fdf3047e95a3f012583dc3c0bbd7ca1010e32ed9e9fc5760ad4292"}, |
| 35 | 37 | "iconv": {:hex, :iconv, "1.0.14", "719a151d124bb356d9054c30f6256f6219f5f9e95ceb748db9ad5f8e28fb3083", [:rebar3], [], "hexpm", "54e2a1bdac2de91292d46d251528a1e1cd62f4709d6572b38b537e9d30599740"}, |
@@ -44,14 +46,18 @@
| 44 | 46 | "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, |
| 45 | 47 | "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, |
| 46 | 48 | "mimerl": {:hex, :mimerl, "1.5.0", "f35aca6f23242339b3666e0ac0702379e362b469d0aea167f6cc713547e777ed", [:rebar3], [], "hexpm", "db648ce065bae14ea84ca8b5dd123f42f49417cef693541110bf6f9e9be9ecc4"}, |
| 49 | + "mint": {:hex, :mint, "1.9.3", "3337184d69179695c7a9f1714d92c11e629d36c8c037a21cf490131d3d150554", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5f7c9342480c069dbbc4eeac3490303c9e01870ff01a7f1d29b6107054fc1e74"}, | |
| 47 | 50 | "nebulex": {:hex, :nebulex, "2.6.5", "b1caa82ef46e9cf8c28f170b432c6938747741ab5d84b2c944277180b8ad8695", [:mix], [{:decorator, "~> 1.4", [hex: :decorator, repo: "hexpm", optional: true]}, {:shards, "~> 1.1", [hex: :shards, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "4eb4092058ba53289cb4d5a1b109de6fd094883dfc84a1c2f2ccc57e61a24935"}, |
| 48 | 51 | "nimble_csv": {:hex, :nimble_csv, "1.3.0", "b7f998dc62b222bce9596e46f028c7a5af04cb5dde6df2ea197c583227c54971", [:mix], [], "hexpm", "41ccdc18f7c8f8bb06e84164fc51635321e80d5a3b450761c4997d620925d619"}, |
| 49 | 52 | "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, |
| 50 | 53 | "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, |
| 54 | + "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, | |
| 51 | 55 | "oban": {:hex, :oban, "2.19.4", "045adb10db1161dceb75c254782f97cdc6596e7044af456a59decb6d06da73c1", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5fcc6219e6464525b808d97add17896e724131f498444a292071bf8991c99f97"}, |
| 52 | 56 | "oban_live_dashboard": {:hex, :oban_live_dashboard, "0.1.1", "8aa4ceaf381c818f7d5c8185cc59942b8ac82ef0cf559881aacf8d3f8ac7bdd3", [:mix], [{:oban, "~> 2.15", [hex: :oban, repo: "hexpm", optional: false]}, {:phoenix_live_dashboard, "~> 0.7", [hex: :phoenix_live_dashboard, repo: "hexpm", optional: false]}], "hexpm", "16dc4ce9c9a95aa2e655e35ed4e675652994a8def61731a18af85e230e1caa63"}, |
| 57 | + "octo_fetch": {:hex, :octo_fetch, "0.5.0", "f50701568b9fc752656367f82cc134d5fbefff37c5a0e8ddfcceb02ceee3f5fc", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "6226cc3c14ca948ee9f25fb0446322e5c288e215da9beba7899b6b5f4cd3ccb0"}, | |
| 53 | 58 | "parent": {:hex, :parent, "0.12.1", "495c4386f06de0df492e0a7a7199c10323a55e9e933b27222060dd86dccd6d62", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2ab589ef1f37bfcedbfb5ecfbab93354972fb7391201b8907a866dadd20b39d1"}, |
| 54 | 59 | "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, |
| 60 | + "peep": {:hex, :peep, "3.5.0", "9f6ead7b0f2c684494200c8fc02e7e62e8c459afe861b29bd859e4c96f402ed8", [:mix], [{:nimble_options, "~> 1.1", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:plug, "~> 1.16", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5a73a99c6e60062415efeb7e536a663387146463a3d3df1417da31fd665ac210"}, | |
| 55 | 61 | "phoenix": {:hex, :phoenix, "1.7.24", "4cb76aed6d3f03878893769020e97c4394ee95b62b2b2d6313c20f66d7d37baa", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "a283a9d91517116166244fdd8ed8b405c142774dc39b4a4047d179cecca9c09f"}, |
| 56 | 62 | "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.5", "c4ef322acd15a574a8b1a08eff0ee0a85e73096b53ce1403b6563709f15e1cea", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "26ec3208eef407f31b748cadd044045c6fd485fbff168e35963d2f9dfff28d4b"}, |
| 57 | 63 | "phoenix_html": {:hex, :phoenix_html, "4.3.0", "d3577a5df4b6954cd7890c84d955c470b5310bb49647f0a114a6eeecc850f7ad", [:mix], [], "hexpm", "3eaa290a78bab0f075f791a46a981bbe769d94bc776869f4f3063a14f30497ad"}, |
@@ -69,6 +75,7 @@
| 69 | 75 | "poison": {:hex, :poison, "5.0.0", "d2b54589ab4157bbb82ec2050757779bfed724463a544b6e20d79855a9e43b24", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "11dc6117c501b80c62a7594f941d043982a1bd05a1184280c0d9166eb4d8d3fc"}, |
| 70 | 76 | "polymorphic_embed": {:hex, :polymorphic_embed, "5.0.3", "37444e0af941026a2c29b0539b6471bdd6737a6492a19264bf2bb0118e3ac242", [:mix], [{:attrs, "~> 0.6", [hex: :attrs, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_html_helpers, "~> 1.0", [hex: :phoenix_html_helpers, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.20 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}], "hexpm", "2fed44f57abf0a0fc7642e0eb0807a55b65de1562712cc0620772cbbb80e49c1"}, |
| 71 | 77 | "postgrex": {:hex, :postgrex, "0.22.3", "bf65941737ee7a9adbe4a64c91080310d11703da343e8ac9188aacb9eb9f6f02", [:mix], [{:db_connection, "~> 2.9", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "f018c13752b2b46e8d35d7e2d84c3276557cbfd880769109021a1d0ee36c1cfe"}, |
| 78 | + "prom_ex": {:hex, :prom_ex, "1.11.0", "1f6d67f2dead92224cb4f59beb3e4d319257c5728d9638b4a5e8ceb51a4f9c7e", [:mix], [{:absinthe, ">= 1.7.0", [hex: :absinthe, repo: "hexpm", optional: true]}, {:broadway, ">= 1.1.0", [hex: :broadway, repo: "hexpm", optional: true]}, {:ecto, ">= 3.11.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:finch, "~> 0.18", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:oban, ">= 2.10.0", [hex: :oban, repo: "hexpm", optional: true]}, {:octo_fetch, "~> 0.4", [hex: :octo_fetch, repo: "hexpm", optional: false]}, {:peep, "~> 3.0", [hex: :peep, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.7.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, ">= 0.20.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, ">= 1.16.0", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 2.6.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, ">= 1.0.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}, {:telemetry_metrics_prometheus_core, "~> 1.2", [hex: :telemetry_metrics_prometheus_core, repo: "hexpm", optional: false]}, {:telemetry_poller, "~> 1.1", [hex: :telemetry_poller, repo: "hexpm", optional: false]}], "hexpm", "76b074bc3730f0802978a7eb5c7091a65473eaaf07e99ec9e933138dcc327805"}, | |
| 72 | 79 | "protobuf": {:hex, :protobuf, "0.17.0", "39e24e43c9648e148feba16ed51100b5b2028ea900b55460377b0476f6e10613", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "ca6c91f6f63e2c147b47f03eefd10b80538aa6fc55ff4b12b795efb786b0152f"}, |
| 73 | 80 | "rabbit_common": {:hex, :rabbit_common, "4.2.1", "1d64e391e12116b76b1425eb96b7552de51f0301093eba669b5334f4759cc1e8", [:make, :rebar3], [{:credentials_obfuscation, "3.5.0", [hex: :credentials_obfuscation, repo: "hexpm", optional: false]}, {:ranch, "2.2.0", [hex: :ranch, repo: "hexpm", optional: false]}, {:recon, "2.5.6", [hex: :recon, repo: "hexpm", optional: false]}, {:thoas, "1.2.1", [hex: :thoas, repo: "hexpm", optional: false]}], "hexpm", "ff509b07e639b1784898c28031e5204fea14260172e4fc339f94405586037e40"}, |
| 74 | 81 | "ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"}, |
@@ -83,7 +90,8 @@
| 83 | 90 | "swoosh": {:hex, :swoosh, "1.27.0", "2df57c342f3854f2d429e6afebf19a03a179976a64006a93750ed81639453f75", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, ">= 1.9.0 and < 5.0.0", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, ">= 6.0.0 and < 8.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5da7d3b11de5d61327275ed599cb311942ea6e23cdbb411981f46ee150cddf76"}, |
| 84 | 91 | "tailwind": {:hex, :tailwind, "0.3.1", "a89d2835c580748c7a975ad7dd3f2ea5e63216dc16d44f9df492fbd12c094bed", [:mix], [], "hexpm", "98a45febdf4a87bc26682e1171acdedd6317d0919953c353fcd1b4f9f4b676a2"}, |
| 85 | 92 | "telemetry": {:hex, :telemetry, "1.4.2", "a0cb522801dffb1c49fe6e30561badffc7b6d0e180db1300df759faa22062855", [:rebar3], [], "hexpm", "928f6495066506077862c0d1646609eed891a4326bee3126ba54b60af61febb1"}, |
| 86 | − "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.2", "2caabe9344ec17eafe5403304771c3539f3b6e2f7fb6a6f602558c825d0d0bfb", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b43db0dc33863930b9ef9d27137e78974756f5f198cae18409970ed6fa5b561"}, | |
| 93 | + "telemetry_metrics": {:hex, :telemetry_metrics, "1.1.0", "5bd5f3b5637e0abea0426b947e3ce5dd304f8b3bc6617039e2b5a008adc02f8f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7b79e8ddfde70adb6db8a6623d1778ec66401f366e9a8f5dd0955c56bc8ce67"}, | |
| 94 | + "telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.2.1", "c9755987d7b959b557084e6990990cb96a50d6482c683fb9622a63837f3cd3d8", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5e2c599da4983c4f88a33e9571f1458bf98b0cf6ba930f1dc3a6e8cf45d5afb6"}, | |
| 87 | 95 | "telemetry_poller": {:hex, :telemetry_poller, "1.2.0", "ba82e333215aed9dd2096f93bd1d13ae89d249f82760fcada0850ba33bac154b", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7216e21a6c326eb9aa44328028c34e9fd348fb53667ca837be59d0aa2a0156e8"}, |
| 88 | 96 | "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, |
| 89 | 97 | "thoas": {:hex, :thoas, "1.2.1", "19a25f31177a17e74004d4840f66d791d4298c5738790fa2cc73731eb911f195", [:rebar3], [], "hexpm", "e38697edffd6e91bd12cea41b155115282630075c2a727e7a6b2947f5408b86a"}, |
Parents: 12afe8a