feat: add runtime statistics to healthcheck endpoint #80

Merged
sneak merged 1 commits from feature/healthcheck-runtime-stats into main 2026-03-17 12:43:40 +01:00
Collaborator

Summary

Expands the /.well-known/healthcheck.json endpoint with runtime statistics, giving operators visibility into server load and usage patterns.

closes #74

New healthcheck fields

Field Source Description
sessions DB Current active session count
clients DB Current connected client count
queuedLines DB Total entries in client output queues
channels DB Current channel count
connectionsSinceBoot Memory Total client connections since server start
sessionsSinceBoot Memory Total sessions created since server start
messagesSinceBoot Memory Total PRIVMSG/NOTICE messages since server start

Implementation

  • New internal/stats package — atomic counters for boot-scoped metrics (connectionsSinceBoot, sessionsSinceBoot, messagesSinceBoot). Thread-safe via sync/atomic.
  • New DB queriesGetClientCount() and GetQueueEntryCount() for current snapshot counts.
  • Healthcheck changesHealthcheck() now accepts context.Context to query the database. Response struct extended with all 7 new fields. DB-derived stats populated with graceful error handling (logged, not fatal).
  • Counter instrumentation — Increments added at:
    • handleCreateSessionIncrSessions + IncrConnections
    • handleRegisterIncrSessions + IncrConnections
    • handleLoginIncrConnections (new client for existing session)
    • handlePrivmsgIncrMessages (covers both PRIVMSG and NOTICE)
  • Wired via fxstats.Tracker provided through Uber fx DI in both production and test setups.

Tests

  • internal/stats/stats_test.go — 5 tests covering all counter operations (100% coverage)
  • TestHealthcheckRuntimeStatsFields — verifies all 7 new fields are present in the response
  • TestHealthcheckRuntimeStatsValues — end-to-end: creates a session, joins a channel, sends a message, then verifies counts are nonzero

README

Updated healthcheck documentation with full response shape, field descriptions, and project structure listing for internal/stats/.

## Summary Expands the `/.well-known/healthcheck.json` endpoint with runtime statistics, giving operators visibility into server load and usage patterns. closes #74 ## New healthcheck fields | Field | Source | Description | |-------|--------|-------------| | `sessions` | DB | Current active session count | | `clients` | DB | Current connected client count | | `queuedLines` | DB | Total entries in client output queues | | `channels` | DB | Current channel count | | `connectionsSinceBoot` | Memory | Total client connections since server start | | `sessionsSinceBoot` | Memory | Total sessions created since server start | | `messagesSinceBoot` | Memory | Total PRIVMSG/NOTICE messages since server start | ## Implementation - **New `internal/stats` package** — atomic counters for boot-scoped metrics (`connectionsSinceBoot`, `sessionsSinceBoot`, `messagesSinceBoot`). Thread-safe via `sync/atomic`. - **New DB queries** — `GetClientCount()` and `GetQueueEntryCount()` for current snapshot counts. - **Healthcheck changes** — `Healthcheck()` now accepts `context.Context` to query the database. Response struct extended with all 7 new fields. DB-derived stats populated with graceful error handling (logged, not fatal). - **Counter instrumentation** — Increments added at: - `handleCreateSession` → `IncrSessions` + `IncrConnections` - `handleRegister` → `IncrSessions` + `IncrConnections` - `handleLogin` → `IncrConnections` (new client for existing session) - `handlePrivmsg` → `IncrMessages` (covers both PRIVMSG and NOTICE) - **Wired via fx** — `stats.Tracker` provided through Uber fx DI in both production and test setups. ## Tests - `internal/stats/stats_test.go` — 5 tests covering all counter operations (100% coverage) - `TestHealthcheckRuntimeStatsFields` — verifies all 7 new fields are present in the response - `TestHealthcheckRuntimeStatsValues` — end-to-end: creates a session, joins a channel, sends a message, then verifies counts are nonzero ## README Updated healthcheck documentation with full response shape, field descriptions, and project structure listing for `internal/stats/`.
clawbot added 1 commit 2026-03-17 10:44:32 +01:00
feat: add runtime statistics to healthcheck endpoint
All checks were successful
check / check (push) Successful in 1m4s
1099fc372f
Add the following counters to the healthcheck JSON response:

- sessions: current active session count (from DB)
- clients: current connected client count (from DB)
- queuedLines: total entries in client output queues (from DB)
- channels: current channel count (from DB)
- connectionsSinceBoot: total client connections since server start
- sessionsSinceBoot: total sessions created since server start
- messagesSinceBoot: total PRIVMSG/NOTICE messages since server start

Implementation:
- New internal/stats package with atomic counters for boot-scoped metrics
- New DB queries GetClientCount and GetQueueEntryCount
- Healthcheck.Healthcheck() now accepts context for DB queries
- Counter increments in session creation, registration, login, and messaging
- Stats tracker wired via Uber fx dependency injection
- Unit tests for stats package (100% coverage) and integration tests
- README updated with full healthcheck response documentation

closes #74
clawbot added the needs-reviewbot labels 2026-03-17 10:45:05 +01:00
clawbot reviewed 2026-03-17 10:50:17 +01:00
clawbot left a comment
Author
Collaborator

Review: PR #80 — feat: add runtime statistics to healthcheck endpoint

Closes: #74


Requirements Checklist (7/7 )

All 7 counters from #74 are present and correctly sourced:

# Requirement Field Source Status
1 Total session count sessions GetUserCount(ctx)sessions table
2 Total client-session count clients GetClientCount(ctx)clients table
3 Total number of output queued lines queuedLines GetQueueEntryCount(ctx)client_queues table
4 Total number of channels channels GetChannelCount(ctx)channels table
5 Total connections since boot connectionsSinceBoot Atomic counter via stats.Tracker
6 Total sessions since boot sessionsSinceBoot Atomic counter via stats.Tracker
7 Total messages since boot messagesSinceBoot Atomic counter via stats.Tracker

Counter Instrumentation Accuracy

Call site Counters incremented Correct?
handleCreateSession (after successful DB create) IncrSessions + IncrConnections
handleRegister (after successful DB register) IncrSessions + IncrConnections
handleLogin (after successful DB login) IncrConnections only (login adds client to existing session, not new session)
handlePrivmsg (after validation, before routing) IncrMessages (covers both PRIVMSG and NOTICE via shared dispatchCommand path)

All counters are incremented after error checks, so only successful operations are counted. No missed paths — handleCreateSession, handleRegister, and handleLogin are the only three session/connection creation entry points.

Policy Compliance

  • Doc comments on all exported types/functions: Package stats has package comment; Tracker, New(), and all 6 methods have doc comments.
  • No code in cmd/ beyond bootstrapping: Only stats.New added to fx providers.
  • Error handling: DB errors in populateDBStats are logged via slog and gracefully degraded (zero value returned). Non-fatal — healthcheck still responds.
  • JSON tags: All new fields use camelCase.
  • No inline error handling: All if err != nil use plain assignment pattern.
  • Blank line before return statements: Consistent with existing codebase patterns.
  • Tests for new exported types: stats_test.go achieves 100% statement coverage. Integration tests TestHealthcheckRuntimeStatsFields and TestHealthcheckRuntimeStatsValues verify end-to-end correctness.
  • DI wiring: stats.Tracker properly provided via fx in both production (cmd/neoircd/main.go) and test harness (api_test.go).
  • No new dependencies added.

Code Quality Notes

  • Thread safety via sync/atomic is the right approach for boot-scoped counters — simple, zero-contention, no mutex overhead.
  • populateDBStats cleanly separates DB-derived stats from in-memory counters. Graceful degradation on DB errors is correct for a healthcheck — you don't want the healthcheck itself to fail because a COUNT query timed out.
  • New DB queries (GetClientCount, GetQueueEntryCount) follow the exact same pattern as existing GetUserCount and GetChannelCount.
  • README documentation accurately reflects the new response shape with a clear field description table.

Build Result

docker build . passes. All tests green:

  • internal/stats — 5/5 tests pass, 100% coverage
  • internal/handlers — all tests pass including 2 new integration tests
  • All other packages unaffected

Verdict: PASS

Clean implementation. All 7 required counters present and correctly sourced. Policy-compliant. Well-tested. Build green.

## Review: PR #80 — feat: add runtime statistics to healthcheck endpoint **Closes:** [#74](https://git.eeqj.de/sneak/chat/issues/74) --- ### Requirements Checklist (7/7 ✅) All 7 counters from [#74](https://git.eeqj.de/sneak/chat/issues/74) are present and correctly sourced: | # | Requirement | Field | Source | Status | |---|------------|-------|--------|--------| | 1 | Total session count | `sessions` | `GetUserCount(ctx)` → `sessions` table | ✅ | | 2 | Total client-session count | `clients` | `GetClientCount(ctx)` → `clients` table | ✅ | | 3 | Total number of output queued lines | `queuedLines` | `GetQueueEntryCount(ctx)` → `client_queues` table | ✅ | | 4 | Total number of channels | `channels` | `GetChannelCount(ctx)` → `channels` table | ✅ | | 5 | Total connections since boot | `connectionsSinceBoot` | Atomic counter via `stats.Tracker` | ✅ | | 6 | Total sessions since boot | `sessionsSinceBoot` | Atomic counter via `stats.Tracker` | ✅ | | 7 | Total messages since boot | `messagesSinceBoot` | Atomic counter via `stats.Tracker` | ✅ | ### Counter Instrumentation Accuracy ✅ | Call site | Counters incremented | Correct? | |-----------|---------------------|----------| | `handleCreateSession` (after successful DB create) | `IncrSessions` + `IncrConnections` | ✅ | | `handleRegister` (after successful DB register) | `IncrSessions` + `IncrConnections` | ✅ | | `handleLogin` (after successful DB login) | `IncrConnections` only | ✅ (login adds client to existing session, not new session) | | `handlePrivmsg` (after validation, before routing) | `IncrMessages` | ✅ (covers both PRIVMSG and NOTICE via shared `dispatchCommand` path) | All counters are incremented **after** error checks, so only successful operations are counted. No missed paths — `handleCreateSession`, `handleRegister`, and `handleLogin` are the only three session/connection creation entry points. ### Policy Compliance ✅ - **Doc comments on all exported types/functions:** Package `stats` has package comment; `Tracker`, `New()`, and all 6 methods have doc comments. ✅ - **No code in `cmd/` beyond bootstrapping:** Only `stats.New` added to fx providers. ✅ - **Error handling:** DB errors in `populateDBStats` are logged via `slog` and gracefully degraded (zero value returned). Non-fatal — healthcheck still responds. ✅ - **JSON tags:** All new fields use camelCase. ✅ - **No inline error handling:** All `if err != nil` use plain assignment pattern. ✅ - **Blank line before return statements:** Consistent with existing codebase patterns. ✅ - **Tests for new exported types:** `stats_test.go` achieves 100% statement coverage. Integration tests `TestHealthcheckRuntimeStatsFields` and `TestHealthcheckRuntimeStatsValues` verify end-to-end correctness. ✅ - **DI wiring:** `stats.Tracker` properly provided via fx in both production (`cmd/neoircd/main.go`) and test harness (`api_test.go`). ✅ - **No new dependencies added.** ✅ ### Code Quality Notes - Thread safety via `sync/atomic` is the right approach for boot-scoped counters — simple, zero-contention, no mutex overhead. - `populateDBStats` cleanly separates DB-derived stats from in-memory counters. Graceful degradation on DB errors is correct for a healthcheck — you don't want the healthcheck itself to fail because a COUNT query timed out. - New DB queries (`GetClientCount`, `GetQueueEntryCount`) follow the exact same pattern as existing `GetUserCount` and `GetChannelCount`. - README documentation accurately reflects the new response shape with a clear field description table. ### Build Result ✅ `docker build .` passes. All tests green: - `internal/stats` — 5/5 tests pass, 100% coverage - `internal/handlers` — all tests pass including 2 new integration tests - All other packages unaffected ### Verdict: **PASS** ✅ Clean implementation. All 7 required counters present and correctly sourced. Policy-compliant. Well-tested. Build green.
clawbot added merge-ready and removed needs-review labels 2026-03-17 10:50:48 +01:00
sneak was assigned by clawbot 2026-03-17 10:50:48 +01:00
sneak merged commit 052674b4ee into main 2026-03-17 12:43:40 +01:00
sneak deleted branch feature/healthcheck-runtime-stats 2026-03-17 12:43:40 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/chat#80