Skip to content

fix(monitoring): scrape each DAO API replica and alert on open circuits - #2151

Merged
brunod-e merged 4 commits into
devfrom
brunod-e/monitoring-replica-scrape
Sep 15, 2026
Merged

brunod-e merged 4 commits into
devfrom
brunod-e/monitoring-replica-scrape

Conversation

@brunod-e

@brunod-e brunod-e commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Problema

http_server_requests_total (e o histograma de duração) das DAO APIs estava inflada em ~4.000x. As APIs rodam com 2+ réplicas na Railway atrás de um hostname privado, e o job usava static_configs com um único target host:porta: cada scrape cai numa réplica diferente, o contador "cai", e rate()/increase() tratam como reset e somam o valor inteiro (9.875 resets/dia só na ENS API). Valores brutos do contador alternando entre duas sequências (11785, 11787, 11790 / 11746, 11747, 11749) confirmaram. Ground truth: ~8 req/min nos logs da ENS API contra 32.000/min na métrica.

Isso levou a um diagnóstico errado durante a investigação da DEV-1163 (o notification-system foi apontado como causa das quedas por "2.600 req/s" que nunca existiram).

Mudanças

  • entrypoint.prometheus.sh: o job anticapture-<dao>-api usa dns_sd_configs (AAAA) no hostname de <DAO>_API_ENDPOINT, um target por réplica. Indexers seguem estáticos (Ponder é instância única). <DAO>_API_ENDPOINT continua em host:porta.
  • alerts.yml:
    • GatefulCircuitOpen (critical): circuit_breaker_state == 2 por 2 min, por nome do breaker. É o sinal direto de "usuários vendo 503 para este DAO/rota".
    • DaoApiRouteFailing (warning): rota de uma DAO API com mais de 50% de 5xx durante 1h (mínimo 10 requests). Pega falhas determinísticas de baixo volume, como as duas rotas (Dune 404, CoinGecko 404) que derrubaram ENS e FLUID em agosto e que o HighErrorRate global não destaca.
  • README: documenta o motivo do dns_sd e o pitfall da métrica.

Observação para o time

HighErrorRate e HighLatency dispararam em ~30 dos últimos 45 dias (incluindo 26-28/08). Eles funcionam, mas viraram ruído; vale rever thresholds/roteamento em separado. Não alterei nada nesses dois.

Verificação

  • alerts.yml parseia como YAML válido; sh -n no entrypoint OK; trecho gerado por DAO validado.
  • Não há promtool no ambiente; sugiro promtool check rules infra/monitoring/alerts.yml no CI/local antes do merge.

🤖 Generated with Claude Code

DAO APIs run with several Railway replicas behind one private hostname, and a
static target was answered by a different replica at every scrape, so their
counters looked like they reset constantly and rate() reported thousands of
times the real traffic (32,000 req/min for the ENS API against ~8 req/min in
its logs). The API job now resolves the hostname's AAAA records and scrapes
every replica as its own target.

Adds GatefulCircuitOpen (a DAO route is being rejected by the gateway) and
DaoApiRouteFailing (one route failing most of the time for an hour), the two
signals that would have pointed straight at the causes of the late-August
outages.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
anticapture-storybook Ready Ready Preview Sep 14, 2026 5:07pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
anticapture Ignored Ignored Sep 14, 2026 5:07pm UTC

Request Review

@railway-app

railway-app Bot commented Sep 3, 2026

Copy link
Copy Markdown

🚅 Deployed to the anticapture-pr-2151 environment in anticapture-infra

Service Status Web Updated
prometheus ✅ Success (View Logs) Sep 14, 2026 at 5:11 pm UTC
gateful ✅ Success (View Logs) Web Sep 14, 2026 at 5:10 pm UTC
authful ✅ Success (View Logs) Web Sep 14, 2026 at 5:10 pm UTC
loki ✅ Success (View Logs) Sep 14, 2026 at 5:08 pm UTC
tempo ✅ Success (View Logs) Sep 14, 2026 at 5:08 pm UTC
grafana ✅ Success (View Logs) Web Sep 14, 2026 at 5:07 pm UTC
alertmanager ✅ Success (View Logs) Web Sep 14, 2026 at 5:07 pm UTC
otelcol ✅ Success (View Logs) Sep 14, 2026 at 5:07 pm UTC
ens-indexer-offchain ✅ Success (View Logs) Sep 3, 2026 at 6:17 pm UTC
uniswap-indexer-offchain ✅ Success (View Logs) Sep 3, 2026 at 6:14 pm UTC
shutter-indexer-offchain ✅ Success (View Logs) Sep 3, 2026 at 6:09 pm UTC
compound-indexer-offchain ✅ Success (View Logs) Sep 3, 2026 at 6:07 pm UTC
gitcoin-indexer-offchain ✅ Success (View Logs) Sep 3, 2026 at 6:07 pm UTC
mcp ✅ Success (View Logs) Web Sep 3, 2026 at 12:29 pm UTC
docs ✅ Success (View Logs) Web Sep 3, 2026 at 12:29 pm UTC
obol-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
tornado-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
lil-nouns-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
uniswap-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
ens-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
obol-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
compound-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
nouns-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
aave-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
ens-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
scroll-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
nouns-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
gitcoin-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
shutter-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
uniswap-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
lil-nouns-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
fluid-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
tornado-api ✅ Success (View Logs) Sep 3, 2026 at 12:29 pm UTC
fluid-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
compound-api ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
address-enrichment ✅ Success (View Logs) Web Sep 3, 2026 at 12:28 pm UTC
gitcoin-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
shutter-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
aave-indexer ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
ens-relayer ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
erpc ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
scroll-api ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
nodeful ✅ Success (View Logs) Sep 3, 2026 at 12:28 pm UTC
user-api ✅ Success (View Logs) Web Sep 3, 2026 at 12:28 pm UTC

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4394684da9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread infra/monitoring/entrypoint.prometheus.sh
Comment thread infra/monitoring/alerts.yml Outdated
Comment thread infra/monitoring/alerts.yml Outdated
…tune DaoApiRouteFailing

Review feedback: a DNS-discovered job with no replicas has no up series, so
add a Prometheus self-scrape and an ApiNoReplicas alert on
prometheus_sd_discovered_targets. DaoApiRouteFailing already smooths over a
1h window, so its for clause drops to 10m (a short burst of failures now
alerts instead of aging out of the window first), and the ratio is expressed
in percent so the annotation prints the right number.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🔍 Vercel preview: https://anticapture-lmbcuhnq4-ful.vercel.app

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 53f65db6b4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread infra/monitoring/entrypoint.prometheus.sh
With one up series per discovered replica, a single replica restarting
during a rolling deploy would have fired the critical ApiDown. ApiDown now
requires every replica of the job to be down; ApiReplicaDown (warning) keeps
the per-instance signal.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45c79fdb7a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread infra/monitoring/entrypoint.prometheus.sh
… by job

DAO API jobs can have several replicas via DNS discovery, each with its own
process_cpu_time_seconds_total series. Summing by job before comparing to 80%
let two healthy replicas at 45% CPU each falsely alert. Aggregate by
(job, instance) instead, matching the ApiReplicaDown per-instance pattern.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@railway-app
railway-app Bot temporarily deployed to anticapture-infra / anticapture-pr-2151 September 14, 2026 17:05 Destroyed
@brunod-e
brunod-e merged commit a706c9e into dev Sep 15, 2026
60 checks passed
@brunod-e
brunod-e deleted the brunod-e/monitoring-replica-scrape branch September 15, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants