Skip to content

feat(metrics): per-source ingest error counter (hotblocks_ingest_source_errors_total)#81

Draft
mo4islona wants to merge 1 commit into
masterfrom
feat/ingest-source-error-metric
Draft

feat(metrics): per-source ingest error counter (hotblocks_ingest_source_errors_total)#81
mo4islona wants to merge 1 commit into
masterfrom
feat/ingest-source-error-metric

Conversation

@mo4islona

Copy link
Copy Markdown
Contributor

What

Adds a hotblocks_ingest_source_errors_total{source, kind} counter recording ingestion errors from upstream data sources.

  • source — the upstream host (e.g. evm-uniblock-binance-mainnet-hotblocks-service.evm-hotblocks)
  • kind — coarse class: connect / timeout / http / decode / io / other
  • (plus pod / namespace from the scrape)

Why

Ingest data-source errors (DNS/connect failures, upstream 5xx, timeouts) were only emitted as WARN logs — there was no metric, so a stalled ingest (all sources failing to connect/read) was invisible on dashboards and unalertable.

This came out of investigating the recurring post-deploy freshness freezes (NET-408): during those windows the pod's own logs weren't even shipped (fluent-bit gap), while Prometheus kept scraping — so a metric is the only reliable signal there.

The source label lets a permanently-dead endpoint (which spams errors continuously behind a healthy fallback) be told apart from a fresh incident where many otherwise-healthy sources start failing at once:

# number of distinct sources erroring — spikes on a real incident,
# unaffected by the chronic-dead baseline
count by (pod) (sum by (pod, source) (rate(hotblocks_ingest_source_errors_total{kind="connect"}[5m])) > 0)

How

  • DataClient::error_kind() / source_label() — new trait methods with default impls ("other" / "unknown"); the reqwest-specific classification stays in ReqwestDataClient.
  • Recorded in StandardDataSource::on_error (sqd-data-source), registered in sqd-hotblocks::metrics::build_metrics_registry.

Draft — the complementary portal-side fix (read/TTFB timeout on the hotblocks client, so a slow/starting pod can't hang /stream) is tracked separately.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UBLDJBHu2zvs75C4XdDFrL

Add hotblocks_ingest_source_errors_total{source, kind} recording upstream
data-source ingestion errors (connect/dns/timeout/http/...), which were
previously only WARN logs and thus invisible on dashboards / unalertable.

- DataClient::error_kind() / source_label(): new trait methods with default
  impls; the reqwest-specific classification stays in ReqwestDataClient
- recorded in StandardDataSource::on_error, registered in hotblocks metrics
- the `source` label separates a chronically-dead endpoint (constant error
  spam, healthy fallback) from a real incident where many sources fail at once

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UBLDJBHu2zvs75C4XdDFrL
@mo4islona mo4islona force-pushed the feat/ingest-source-error-metric branch from a197df6 to 88b8129 Compare July 8, 2026 15:36
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.

1 participant