From d0898c86500e40f19ce9881b32c6fa77adc3dade Mon Sep 17 00:00:00 2001 From: Kevin Lutzer Date: Sun, 17 Sep 2023 11:48:40 -0400 Subject: [PATCH] Expose total subscribers and topics in the /v1/stats api --- server/server.go | 19 +++++++++++++++++-- server/server_test.go | 13 +++++++------ server/types.go | 6 ++++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/server/server.go b/server/server.go index 0ab36524..69fbc55f 100644 --- a/server/server.go +++ b/server/server.go @@ -631,14 +631,29 @@ func (s *Server) handleDocs(w http.ResponseWriter, r *http.Request, _ *visitor) // handleStats returns the publicly available server stats func (s *Server) handleStats(w http.ResponseWriter, _ *http.Request, _ *visitor) error { s.mu.RLock() + + var totalTopics, totalSubscriptions int64 + for _, t := range s.topics { + if t.Stale() { + continue + } + + totalTopics += 1 + subscribers, _ := t.Stats() + totalSubscriptions += int64(subscribers) + } + messages, n, rate := s.messages, len(s.messagesHistory), float64(0) if n > 1 { rate = float64(s.messagesHistory[n-1]-s.messagesHistory[0]) / (float64(n-1) * s.config.ManagerInterval.Seconds()) } + s.mu.RUnlock() response := &apiStatsResponse{ - Messages: messages, - MessagesRate: rate, + Messages: messages, + MessagesRate: rate, + TotalTopics: totalTopics, + TotalSubscriptions: totalSubscriptions, } return s.writeJSON(w, response) } diff --git a/server/server_test.go b/server/server_test.go index 647268fb..2633a12c 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -6,8 +6,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "golang.org/x/crypto/bcrypt" - "heckel.io/ntfy/user" "io" "math/rand" "net/http" @@ -22,6 +20,9 @@ import ( "testing" "time" + "golang.org/x/crypto/bcrypt" + "heckel.io/ntfy/user" + "github.com/SherClockHolmes/webpush-go" "github.com/stretchr/testify/require" "heckel.io/ntfy/log" @@ -2501,7 +2502,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) { response := request(t, s, "GET", "/v1/stats", "", nil) require.Equal(t, 200, response.Code) - require.Equal(t, `{"messages":5,"messages_rate":0}`+"\n", response.Body.String()) + require.Equal(t, `{"messages":5,"messages_rate":0,"total_topics":1,"total_subscriptions":0}`+"\n", response.Body.String()) // Run manager and see message history update s.execManager() @@ -2509,7 +2510,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) { response = request(t, s, "GET", "/v1/stats", "", nil) require.Equal(t, 200, response.Code) - require.Equal(t, `{"messages":5,"messages_rate":2.5}`+"\n", response.Body.String()) // 5 messages in 2 seconds = 2.5 messages per second + require.Equal(t, `{"messages":5,"messages_rate":2.5,"total_topics":1,"total_subscriptions":0}`+"\n", response.Body.String()) // 5 messages in 2 seconds = 2.5 messages per second // Publish some more messages for i := 0; i < 10; i++ { @@ -2521,7 +2522,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) { response = request(t, s, "GET", "/v1/stats", "", nil) require.Equal(t, 200, response.Code) - require.Equal(t, `{"messages":15,"messages_rate":2.5}`+"\n", response.Body.String()) // Rate did not update yet + require.Equal(t, `{"messages":15,"messages_rate":2.5,"total_topics":1,"total_subscriptions":0}`+"\n", response.Body.String()) // Rate did not update yet // Run manager and see message history update s.execManager() @@ -2529,7 +2530,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) { response = request(t, s, "GET", "/v1/stats", "", nil) require.Equal(t, 200, response.Code) - require.Equal(t, `{"messages":15,"messages_rate":3.75}`+"\n", response.Body.String()) // 15 messages in 4 seconds = 3.75 messages per second + require.Equal(t, `{"messages":15,"messages_rate":3.75,"total_topics":1,"total_subscriptions":0}`+"\n", response.Body.String()) // 15 messages in 4 seconds = 3.75 messages per second } func TestServer_MessageHistoryMaxSize(t *testing.T) { diff --git a/server/types.go b/server/types.go index eeb566fc..d10a1399 100644 --- a/server/types.go +++ b/server/types.go @@ -244,8 +244,10 @@ type apiHealthResponse struct { } type apiStatsResponse struct { - Messages int64 `json:"messages"` - MessagesRate float64 `json:"messages_rate"` // Average number of messages per second + Messages int64 `json:"messages"` + MessagesRate float64 `json:"messages_rate"` // Average number of messages per second + TotalTopics int64 `json:"total_topics"` + TotalSubscriptions int64 `json:"total_subscriptions"` } type apiUserAddRequest struct {