Commit graph

422 commits

Author SHA1 Message Date
100be89c06
chore: drop OpenTelemetry
Removes the six OTel packages (opentelemetry, _api, _exporter,
_phoenix, _oban, _bandit) and their 9 transitive deps. Tracing was
only wired for Phoenix/Bandit/Oban auto-instrumentation — PromEx
already covers the metrics we actually use on the status page +
Grafana. Also drops the OTEL_EXPORTER_OTLP_ENDPOINT env var and
its comment block from both deployment manifests.
2026-04-24 12:33:38 -05:00
FluxCD
85f402b8dd chore: update prop image to git.mcintire.me/graham/prop:main-1777050827-98aab76 [skip ci] 2026-04-24 17:17:37 +00:00
FluxCD
4a4de2a336 chore: update prop image to git.mcintire.me/graham/prop:main-1777050231-d100e56 [skip ci] 2026-04-24 17:06:30 +00:00
FluxCD
dcec2b3b37 chore: update prop image to git.mcintire.me/graham/prop:main-1777046003-0bc8af2 [skip ci] 2026-04-24 15:57:12 +00:00
FluxCD
b2766c8a90 chore: update prop image to git.mcintire.me/graham/prop:main-1777044777-080257f [skip ci] 2026-04-24 15:36:24 +00:00
FluxCD
35a064b1a4 chore: update prop image to git.mcintire.me/graham/prop:main-1777043748-d88bdd7 [skip ci] 2026-04-24 15:17:56 +00:00
FluxCD
825d2baa10 chore: update prop image to git.mcintire.me/graham/prop:main-1777041055-2900b9a [skip ci] 2026-04-24 14:33:44 +00:00
FluxCD
b057b45fe7 chore: update prop image to git.mcintire.me/graham/prop:main-1777039919-d7d865d [skip ci] 2026-04-24 14:16:37 +00:00
FluxCD
a1ccbeb3e5 chore: update prop image to git.mcintire.me/graham/prop:main-1777038907-5d9f02d [skip ci] 2026-04-24 14:07:30 +00:00
FluxCD
141cb6faf4 chore: update prop image to git.mcintire.me/graham/prop:main-1777037259-5564b67 [skip ci] 2026-04-24 13:30:18 +00:00
FluxCD
0f46d4361a chore: update prop image to git.mcintire.me/graham/prop:main-1776987814-f99d07b [skip ci] 2026-04-23 23:45:30 +00:00
86b2718916
infra(k8s): load-based HPAs, drop anti-affinity, retire talos5
Adds HorizontalPodAutoscaler resources for the three load-responsive
Deployments:

- prop (web): min 2, max 5, averageValue 800m CPU
- prop-grid-rs: min 1, max 4, averageValue 400m
- hrrr-point-rs: min 1, max 4, averageValue 400m
- prop-backfill is intentionally unmanaged (queue-driven, not CPU-bound)

The scale-up policy reacts in 30 s with up-to-2-pods or +100 % per
window; scale-down stabilises over 10 min so the hourly propagation
chain doesn't churn replicas right after the :05 cron.

Removes `spec.replicas` from the HPA-managed Deployments so Flux's
periodic reconcile stops fighting HPA's live scaling decisions.

Drops `podAntiAffinity` from prop, prop-grid-rs, and hrrr-point-rs
so HPA can actually reach its maxReplicas when one physical host has
capacity for two pods; the scheduler picks whatever fits.

Updates runbook + project memory to drop the `talos5` hostname —
Postgres is now addressed strictly by IP (10.0.15.30).
2026-04-23 18:43:18 -05:00
FluxCD
53dc08d659 chore: update prop image to git.mcintire.me/graham/prop:main-1776981668-109c4e1 [skip ci] 2026-04-23 22:04:43 +00:00
FluxCD
731c095840 chore: update prop image to git.mcintire.me/graham/prop:main-1776979115-bd107ee [skip ci] 2026-04-23 21:21:30 +00:00
FluxCD
e33116f759 chore: update prop image to git.mcintire.me/graham/prop:main-1776977813-a7250c3 [skip ci] 2026-04-23 20:59:24 +00:00
FluxCD
d66ac0b2a2 chore: update prop image to git.mcintire.me/graham/prop:main-1776971976-54cabdb [skip ci] 2026-04-23 19:22:42 +00:00
FluxCD
8435d95900 chore: update prop image to git.mcintire.me/graham/prop:main-1776971633-56e6a35 [skip ci] 2026-04-23 19:16:38 +00:00
FluxCD
eb0eaa2416 chore: update prop image to git.mcintire.me/graham/prop:main-1776971365-41573d4 [skip ci] 2026-04-23 19:12:16 +00:00
FluxCD
8324d019ca chore: update prop image to git.mcintire.me/graham/prop:main-1776970997-e7fb34e [skip ci] 2026-04-23 19:07:05 +00:00
FluxCD
ed21758557 chore: update prop image to git.mcintire.me/graham/prop:main-1776968936-764643b [skip ci] 2026-04-23 18:31:46 +00:00
FluxCD
8c0865482c chore: update prop image to git.mcintire.me/graham/prop:main-1776967519-cfb0c51 [skip ci] 2026-04-23 18:07:33 +00:00
FluxCD
a9d13d8eb9 chore: update prop image to git.mcintire.me/graham/prop:main-1776967071-063e9e3 [skip ci] 2026-04-23 18:00:31 +00:00
FluxCD
e88375e50b chore: update prop image to git.mcintire.me/graham/prop:main-1776965182-47ba8d3 [skip ci] 2026-04-23 17:28:47 +00:00
47ba8d3b6d
fix(enrichment): stub IEMRE on permanent failure + bump hot CPU
IemreFetchWorker now writes an empty stub observation when IEM returns
a permanent-failure status (404, 422), mirroring the existing {:ok, []}
path. The backfill cron's next tick sees the stub via
has_iemre_observation?/3, generates no job, and mark_status!/3 flips
the contact's iemre_status from :queued to :complete — draining the
51 contacts that have been stuck behind cancelled out-of-grid IEMRE
jobs.

Raise hot pod CPU limit 2 → 3 so BEAM gets 3 schedulers online.
Observed run queues of [2, 10, 0, 0, 0, 0] on the 2-scheduler
configuration during the :05 propagation chain, starving /live and
/health probe handlers and tripping intermittent liveness timeouts.
2026-04-23 12:26:09 -05:00
FluxCD
da66a613ef chore: update prop image to git.mcintire.me/graham/prop:main-1776960355-b2ff279 [skip ci] 2026-04-23 16:10:27 +00:00
FluxCD
f0f4ce6b33 chore: update prop image to git.mcintire.me/graham/prop:main-1776959622-66fef4f [skip ci] 2026-04-23 15:56:21 +00:00
FluxCD
e4ed923986 chore: update prop image to git.mcintire.me/graham/prop:main-1776898028-004f302 [skip ci] 2026-04-22 22:54:04 +00:00
FluxCD
a5b080f0af chore: update prop image to git.mcintire.me/graham/prop:main-1776894891-47a3e1d [skip ci] 2026-04-22 21:58:48 +00:00
024db2a5b4
perf(fleet): reduce IEM 429 storm and raise probe timeouts
Per-pod IEM rate limiter was 700ms (~1.4 req/sec); four pods put the
fleet at ~5.7 req/sec, above the observed 429 threshold. Retry storm
(Req exponential backoff up to 32s) piled concurrent sleeps on top of
live workers and tripped Bandit's acceptor + Oban's leader heartbeat.

- Raise default interval to 1500ms (~2.7 req/sec fleet).
- Hot pod /live timeout 3s → 5s (acceptor stalls under retry sleeps).
- prop-backfill exec probe period 30s → 120s, timeout 15s → 30s; the
  release CLI round-trips through distributed Erlang and 15s wasn't
  enough under load, restart-looping every ~10 min.
2026-04-22 16:50:58 -05:00
FluxCD
d6d50f7729 chore: update prop image to git.mcintire.me/graham/prop:main-1776884183-04146af [skip ci] 2026-04-22 18:58:47 +00:00
FluxCD
5b41ad00e7 chore: update prop image to git.mcintire.me/graham/prop:main-1776869401-e8c2529 [skip ci] 2026-04-22 14:53:39 +00:00
FluxCD
b92c1ea68b chore: update prop image to git.mcintire.me/graham/prop:main-1776866277-3ec976c [skip ci] 2026-04-22 14:03:26 +00:00
FluxCD
c4a6b8ed8b chore: update prop image to git.mcintire.me/graham/prop:main-1776864939-c192d6f [skip ci] 2026-04-22 13:43:20 +00:00
FluxCD
84f4f93b87 chore: update prop image to git.mcintire.me/graham/prop:main-1776812585-ee7809e [skip ci] 2026-04-21 23:07:11 +00:00
FluxCD
39cc5292a9 chore: update prop image to git.mcintire.me/graham/prop:main-1776812100-c46e89a [skip ci] 2026-04-21 22:57:43 +00:00
c46e89a48f
fix(otel): switch Elixir exporter to OTLP/HTTP to avoid grpcbox shutdown noise
Every prop pod restart was dumping a pair of ArgumentError stack
traces from grpcbox_channel / grpcbox_subchannel terminate/3:

    :ets.select(:gproc, …)
    * 1st argument: the table identifier does not refer to an
      existing ETS table

This is a known grpcbox shutdown race: the OTLP/gRPC transport's
terminate callback tries to look itself up in gproc's ETS just
after gproc's supervisor has already torn the table down. Noisy,
not harmful — but one ArgumentError per restart × N pods adds up.

The OTLP/HTTP transport (port 4318 on the same otel-collector
Service) has no gproc/ETS channel machinery, so shutdown is
quiet. Spans are identical — our collector already accepts both.

- `config/runtime.exs`: default `otlp_protocol: :http_protobuf`,
  with an `OTEL_EXPORTER_OTLP_PROTOCOL=grpc` escape hatch.
- `k8s/deployment.yaml`: point `OTEL_EXPORTER_OTLP_ENDPOINT` at
  :4318 instead of :4317. The Rust workers stay on :4317 — their
  native opentelemetry-otlp transport doesn't share the grpcbox
  bug.
2026-04-21 17:54:44 -05:00
FluxCD
4d5b5f1aee chore: update prop image to git.mcintire.me/graham/prop:main-1776811628-04aa198 [skip ci] 2026-04-21 22:50:40 +00:00
FluxCD
a232670139 chore: update prop image to git.mcintire.me/graham/prop:main-1776810886-4d07f89 [skip ci] 2026-04-21 22:37:16 +00:00
FluxCD
3217b011a4 chore: update prop image to git.mcintire.me/graham/prop:main-1776810088-d3ca2e5 [skip ci] 2026-04-21 22:23:56 +00:00
FluxCD
1c1a253fbe chore: update prop image to git.mcintire.me/graham/prop:main-1776809787-ff950f9 [skip ci] 2026-04-21 22:18:53 +00:00
FluxCD
944c2dc1d4 chore: update prop image to git.mcintire.me/graham/prop:main-1776809397-49d0594 [skip ci] 2026-04-21 22:12:43 +00:00
FluxCD
7e53f6f890 chore: update prop image to git.mcintire.me/graham/prop:main-1776809188-e9a3862 [skip ci] 2026-04-21 22:10:41 +00:00
FluxCD
a0608dfa2f chore: update prop image to git.mcintire.me/graham/prop:main-1776807571-26ef50c [skip ci] 2026-04-21 21:42:32 +00:00
FluxCD
e73f097b75 chore: update prop image to git.mcintire.me/graham/prop:main-1776807271-8ec5d89 [skip ci] 2026-04-21 21:38:29 +00:00
FluxCD
6c57caa902 chore: update prop image to git.mcintire.me/graham/prop:main-1776806062-c56bb91 [skip ci] 2026-04-21 21:28:25 +00:00
a2701780ab
fix(probes): stop DB saturation from SIGKILLing every pod
Investigated why all three prop pods were restart-looping every few
minutes (RESTARTS counts 7–11 in 99m). The trail:

  20:53:33.058 [error] Postgrex.Protocol ("db_conn_10") disconnected:
    client (:"Elixir.Microwaveprop.PromEx.Poller.5000") timed out
    because it queued and checked out the connection for longer than
    15000ms

PromEx's Oban queue-depth poller was scanning the oban_jobs table
every 5s and holding an Ecto connection past its checkout timeout.
That starved the rest of the pool, so /health's `SELECT 1` couldn't
acquire a connection inside the 3s liveness probe timeout, the
kubelet's failureThreshold=3 tripped, and SIGKILL landed on the
BEAM. Every replica cycled on the same cadence.

Two fixes:

1. Split /live (no DB) from /health (DB ping). Kubernetes livenessProbe
   now points at /live so a saturated Ecto pool can never cascade into
   SIGKILL. Readiness still hits /health so a genuine DB outage drains
   the pod from Service endpoints gracefully.

2. Turn off the PromEx Oban plugin in prod via the same flag already
   used in test. The queue-depth query isn't worth pod instability;
   the oban_web dashboard surfaces the same information without
   scanning the job table on a timer.

Locked both down with HealthController tests that verify /live never
touches the Repo (no sandbox owner, controller.live/2 called directly,
200 ok) and /health does (sanity query round-trips).
2026-04-21 16:00:04 -05:00
FluxCD
02bf34db9e chore: update prop image to git.mcintire.me/graham/prop:main-1776798788-48d30f1 [skip ci] 2026-04-21 19:16:25 +00:00
540750b3d3
fix(observability): re-enable OTLP export for Elixir
Set OTEL_EXPORTER_OTLP_ENDPOINT on the prop deployment to the cluster
Collector so Phoenix/Bandit/Oban spans export and link up with
downstream prop-grid-rs / prop-hrrr-point-rs traces in Tempo. Without
this the Elixir app fell back to traces_exporter :none and the Rust
worker spans had no parent, leaving the trace graph disconnected.

The stale comment referenced opentelemetry_ecto as the reason export
was off, but that package was never added to mix.exs (only
opentelemetry_phoenix / _bandit / _oban are listed), so the
span-flood concern no longer applies.
2026-04-21 13:26:27 -05:00
FluxCD
e9b804f628 chore: update prop image to git.mcintire.me/graham/prop:main-1776786279-38ef716 [skip ci] 2026-04-21 15:47:20 +00:00
FluxCD
6c977e250d chore: update prop image to git.mcintire.me/graham/prop:main-1776785420-d61fbd3 [skip ci] 2026-04-21 15:34:05 +00:00