Skip to content

[REQUEST] log and visualize key performance parameters #144

Closed

Description

@Giszmo

Pledge

I pledge to pay $100 if the following gets implemented in its entirety:

Is your feature request related to a problem? Please describe.

I'm tweaking parameters, updating the relay, observing genuine demand fluctuation and probably DOS attacks and only have CPU load, Disk I/O, Bandwidth and some other parameters that are logged for the whole machine to judge if anything is wrong. That's not good for taking informed decisions.

Describe the solution you'd like

  • Log key performance indicators
  • Expose them through a nice interface (serverUrl/stats for example) maybe using grafana or similar

KPIs I would love to see:

  • concurrent websockets open
  • concurrent queries watched
  • websockets opened/closed
  • time from connect to first EOSE
  • time from [e:[] query to EOSE
  • events served
  • Standard system load parameters: CPU, Load, Memory, Disk I/O, Disk Usage, Bandwidth

For some of these parameters, aggregate functions like median, 95th percentile ... would be of interest.

Activity

  1. bleetube commented on Feb 1, 2023

    @bleetube

    I'll also add $100 (of sats) to this pledge. (see below) For an MVP I would be satisfied just with basic metrics for relayed nostr events.

    @Giszmo Most of the stuff you're asking for has little or nothing to do with nostream itself and already handled in other ways, or sounds relatively complex to implement.

    • concurrent websockets open - that's a proxy concern, not nostream
    • concurrent queries watched - medium complexity (minding connection timeouts)
    • websockets opened/closed - I'd guess that's the downstream proxy's concern (e.g nginx), not nostream
    • time from connect to first EOSE - connections are handled by nginx so this is
    • time from [e:[] query to EOSE - high complexity (summary metric)
    • events served - agreed
    • Standard system load parameters: CPU, Load, Memory, Disk I/O, Disk Usage, Bandwidth - just use prometheus + node_exporter or a comparable stack

    Creating a grafana dashboard is easy enough, I can do that side of it. Just need a metrics endpoint. I've done those too, but not in TS.

  2. jmarbach commented on Feb 8, 2023

    @jmarbach

    @Giszmo @bleetube I've shared your request with the Grafana staff to raise awareness on building a metrics collector. No promises.

    Meanwhile, if you just need a metrics endpoint, you can forward whatever Prometheus metrics you'd like to long term storage in Grafana Cloud's managed Mimir service using the Influx proxy:

    https://grafana.com/docs/grafana-cloud/data-configuration/metrics/metrics-influxdb/push-from-telegraf/

  3. bleetube commented on Feb 18, 2023

    @bleetube

    Actually I realized I can do the MVP part I described without touching nodejs. I can just write some python to talk directly to postgres. I have started working on it this weekend in a separate repo:

    https://github.com/bleetube/nostream_exporter (work in progress)

    To start it is exporting one metric, the total count of events in the events table. I have select queries to add in for these metrics as well:

    • top events by kind
    • top talker users by pubkey all time
    • top talker users by pubkey recently
    • count of paid users

    I'll implement those and add in more as time permits. I'll also put together a grafana dashboard to chart them out. And if I think of any good metrics to alert on using alertmanager, I'll add those to the repo as well. Might be nice to send myself an alert if a user is spamming the relay, for instance.

  4. kushagra0902 commented on Apr 9, 2026

    @kushagra0902
    Contributor

    Architecture Comparison

    1. Polling architecture
    • Model: run KPI queries on a fixed interval (for example, every 5s), then push updates.
    • Read load profile: constant, predictable, independent of write traffic.
    • Write load profile: no extra write-side overhead.
    • Freshness latency: bounded by an interval; average latency is roughly half the interval plus query time.
    • Burst behaviour: stable load under write bursts, but can miss sub-interval spikes and appear stale.
    • Idle behaviour: still queries at full interval cadence even when no data changes.
    1. Event-driven architecture
      Model: database triggers emit NOTIFY events on relevant table changes; service LISTENs and recomputes only affected KPI groups probably using a windowed method to avoid recalculation.
      Read load profile: proportional to real changes, near-zero when idle.
      Write load profile: additional trigger and notification overhead on write paths.
      Freshness latency: near real-time (typically notification + recompute + websocket dispatch).
      Burst behaviour: can spike if every write causes full recompute; requires coalescing and KPI invalidation map.
      Idle behaviour: minimal work while no writes occur.

    Steps

    Phase 1: Observability Service Skeleton (PR 1)

    • Goal: Standalone TypeScript process with stable API and websocket contracts.

    • Deliverables:

    • New observability entrypoint under src.

    • Endpoints: GET /health, GET /api/v1/kpis/, websocket /api/v1/kpis/stream.

    • Typed contracts for snapshot payload and websocket messages.

    • Verification and Testing

    • Service boots locally.

    • Health and snapshot routes respond correctly.

    • Websocket handshake succeeds.

    Phase 2: Event-Driven KPI Pipeline (PR 2)

    • Goal: Bring MVP KPIs under observation.
    • Deliverables:
    • KPI collectors for events by kind, plus other, paid users, sats paid, top talkers all-time, top talkers recent.
    • Phase 2 depends on architecture decision

    Phase 3: Dashboard UI (PR 3)

    • Depends on Phase 2 API contract.
    • Goal: deliver a public-first, real-time dashboard consuming snapshot plus websocket updates.
    • Deliverables:
    • Dashboard page served by observability service.
    • KPI cards, event-kind distribution, top-talkers panels, and recent activity feed.
    • Client flow: initial snapshot fetch, websocket subscription, incremental update apply.
    • Reconnect handling, stale state indicator, and heartbeat timeout UX.
    • Responsive behaviour for desktop and mobile.

    Verification Matrix

    1. Correctness
    • KPI values match direct SQL for each metric.
    • Snapshot sequence strictly increases, and clients receive ordered updates.
    1. Freshness
    • Measure write-to-dashboard latency p50 and p95 under representative write rates.
    • Compare the polling baseline estimate to validate the improvement.

    Questions:

    • Polling or real-time-based architecture( imo, polling based architecture will be more stable in heavy traffics)
    • Use of external services to make pipeline and processing( like flinch, although I feel this will complicate unnecessarily)
  5. cameri commented on Apr 9, 2026

    @cameri
    Owner

    what are you thoughts on using OTEL instead for pushing metrics?

  6. kushagra0902 commented on Apr 9, 2026

    @kushagra0902
    Contributor

    what are you thoughts on using OTEL instead for pushing metrics?

    Yes will be a good architecture. Just a small follow-up, is our main intent data observability or real-time performance tracking, as I think a complete OTEL stack of collector and all the necessary modules will increase the overhead.
    If it is just data observability, then I think we can go with a normal PSQL-based architecture

    Please correct me if I am wrong at any point.

  7. cameri commented on Apr 9, 2026

    @cameri
    Owner

    @kushagra0902 let's go with PSQL based architecture

  8. Ferryx349 commented on Aug 18, 2026

    @Ferryx349
    Collaborator

    Hi, I believe this issue is now addressed. The logging and visualization work for nostream’s admin/observability stack is being implemented over the last few months.

    What #144 asked for and what shipped

    1. Log key performance indicators
    Relay metrics are collected via OpenTelemetry and exposed to Prometheus, including:

    • WebSocket connection counts
    • Events accepted/rejected (rate and totals)
    • Process CPU and memory per worker

    2. Expose KPIs through a usable interface
    Operators can view live metrics in two ways:

    • Admin console (/admin/) → Metrics tab with live SSE snapshots from /admin/metrics
    • Grafana → nostream-overview dashboard (embedded in admin UI and available via docker-compose stack)

    3. KPIs from the original checklist

    Requested KPI Where it’s visible
    Concurrent WebSockets Active connections, WebSocket connections (15m)
    Events served Events / sec, Accepted total
    System load (CPU/memory) CPU load %, Memory by worker, CPU by worker
    Rejection visibility Rejected / sec, Rejected total

    Implementation PRs

    Metrics foundation

    Admin API and live metrics

    Visualization UI

    Admin console extensions

    How to try it

    1. Enable admin in settings and set ADMIN_PASSWORD
    2. Run the observability stack (docker compose up) for Prometheus/Grafana
    3. Open /admin/ → Metrics tab for live KPIs, or use Grafana nostream-overview

    If this covers the scope of #144, I’d appreciate closing this issue. Happy to adjust anything if something is still missing from the original checklist.

  9. cameri commented on Aug 19, 2026

    @cameri
    Owner

    Thank you @Ferryx349 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions