From e7fdabc7fad1f9351f2518002faea658f392b85e Mon Sep 17 00:00:00 2001 From: Ronish Bhatt <16808243+sunmoonron@users.noreply.github.com> Date: Mon, 7 Sep 2026 18:51:56 -0400 Subject: [PATCH] metrics: count EVENT messages that fail validation, document what nostr_events_total counts README said nostr_events_total counts events processed while the metric's HELP text and RelayWriter say persisted; the README now matches the code (issue #255). Events that fail validation in the ingester were not counted anywhere; they now increment a new strfry_invalid_events_total counter, leaving strfry_write_rejected_total's meaning (rejected during write) as is. --- README.md | 2 +- src/PrometheusMetrics.h | 5 +++++ src/apps/relay/RelayIngester.cpp | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1510917e..31ca9c36 100644 --- a/README.md +++ b/README.md @@ -257,7 +257,7 @@ The following metrics are available: * **`nostr_client_messages_total{verb}`** - Total number of messages received from clients, broken down by verb (EVENT, REQ, CLOSE, NEG-OPEN, NEG-MSG, NEG-CLOSE) * **`nostr_relay_messages_total{verb}`** - Total number of messages sent to clients, broken down by verb (EVENT, OK, EOSE, NOTICE, NEG-MSG, NEG-ERR) -* **`nostr_events_total{kind}`** - Total number of events processed, broken down by event kind (0, 1, 3, 4, etc.) +* **`nostr_events_total{kind}`** - Total number of events persisted to the DB, broken down by event kind (0, 1, 3, 4, etc.). Rejected and duplicate events are not counted here; see `strfry_write_rejected_total`, `strfry_write_dups_total` and `strfry_invalid_events_total` To scrape these metrics with Prometheus, add a job to your `prometheus.yml`: diff --git a/src/PrometheusMetrics.h b/src/PrometheusMetrics.h index ff092299..2075cac0 100644 --- a/src/PrometheusMetrics.h +++ b/src/PrometheusMetrics.h @@ -101,6 +101,7 @@ class PrometheusMetrics { // Write path performance metrics Counter writtenEventsTotal; Counter rejectedEventsTotal; + Counter invalidEventsTotal; // EVENT messages that failed validation before reaching the writer Counter dupEventsTotal; Counter writeTimeUs; // total microseconds spent in write transactions Gauge lastWriteBatchSize; @@ -152,6 +153,10 @@ class PrometheusMetrics { out << "# TYPE strfry_write_rejected_total counter\n"; out << "strfry_write_rejected_total " << rejectedEventsTotal.get() << "\n"; + out << "# HELP strfry_invalid_events_total Total EVENT messages rejected before the write path because they failed validation\n"; + out << "# TYPE strfry_invalid_events_total counter\n"; + out << "strfry_invalid_events_total " << invalidEventsTotal.get() << "\n"; + out << "# HELP strfry_write_dups_total Total duplicate events skipped\n"; out << "# TYPE strfry_write_dups_total counter\n"; out << "strfry_write_dups_total " << dupEventsTotal.get() << "\n"; diff --git a/src/apps/relay/RelayIngester.cpp b/src/apps/relay/RelayIngester.cpp index 9a5e0009..59f8a02e 100644 --- a/src/apps/relay/RelayIngester.cpp +++ b/src/apps/relay/RelayIngester.cpp @@ -33,6 +33,7 @@ void RelayServer::runIngester(ThreadPool::Thread &thr) { try { ingesterProcessEvent(txn, rsctx, msg->connId, msg->ipAddr, arr[1], writerMsgs); } catch (std::exception &e) { + PrometheusMetrics::getInstance().invalidEventsTotal.inc(); sendOKResponse(msg->connId, arr[1].is_object() && arr[1].at("id").is_string() ? arr[1].at("id").get_string() : "?", false, std::string("invalid: ") + e.what()); if (cfg().relay__logging__invalidEvents) LI << "Rejected invalid event: " << e.what();