Expose total subscribers and topics in the /v1/stats api
This commit is contained in:
parent
528a67722b
commit
d0898c8650
3 changed files with 28 additions and 10 deletions
|
@ -631,14 +631,29 @@ func (s *Server) handleDocs(w http.ResponseWriter, r *http.Request, _ *visitor)
|
||||||
// handleStats returns the publicly available server stats
|
// handleStats returns the publicly available server stats
|
||||||
func (s *Server) handleStats(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
func (s *Server) handleStats(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
||||||
s.mu.RLock()
|
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)
|
messages, n, rate := s.messages, len(s.messagesHistory), float64(0)
|
||||||
if n > 1 {
|
if n > 1 {
|
||||||
rate = float64(s.messagesHistory[n-1]-s.messagesHistory[0]) / (float64(n-1) * s.config.ManagerInterval.Seconds())
|
rate = float64(s.messagesHistory[n-1]-s.messagesHistory[0]) / (float64(n-1) * s.config.ManagerInterval.Seconds())
|
||||||
}
|
}
|
||||||
|
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
response := &apiStatsResponse{
|
response := &apiStatsResponse{
|
||||||
Messages: messages,
|
Messages: messages,
|
||||||
MessagesRate: rate,
|
MessagesRate: rate,
|
||||||
|
TotalTopics: totalTopics,
|
||||||
|
TotalSubscriptions: totalSubscriptions,
|
||||||
}
|
}
|
||||||
return s.writeJSON(w, response)
|
return s.writeJSON(w, response)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"heckel.io/ntfy/user"
|
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -22,6 +20,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"heckel.io/ntfy/user"
|
||||||
|
|
||||||
"github.com/SherClockHolmes/webpush-go"
|
"github.com/SherClockHolmes/webpush-go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"heckel.io/ntfy/log"
|
"heckel.io/ntfy/log"
|
||||||
|
@ -2501,7 +2502,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) {
|
||||||
|
|
||||||
response := request(t, s, "GET", "/v1/stats", "", nil)
|
response := request(t, s, "GET", "/v1/stats", "", nil)
|
||||||
require.Equal(t, 200, response.Code)
|
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
|
// Run manager and see message history update
|
||||||
s.execManager()
|
s.execManager()
|
||||||
|
@ -2509,7 +2510,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) {
|
||||||
|
|
||||||
response = request(t, s, "GET", "/v1/stats", "", nil)
|
response = request(t, s, "GET", "/v1/stats", "", nil)
|
||||||
require.Equal(t, 200, response.Code)
|
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
|
// Publish some more messages
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
|
@ -2521,7 +2522,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) {
|
||||||
|
|
||||||
response = request(t, s, "GET", "/v1/stats", "", nil)
|
response = request(t, s, "GET", "/v1/stats", "", nil)
|
||||||
require.Equal(t, 200, response.Code)
|
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
|
// Run manager and see message history update
|
||||||
s.execManager()
|
s.execManager()
|
||||||
|
@ -2529,7 +2530,7 @@ func TestServer_MessageHistoryAndStatsEndpoint(t *testing.T) {
|
||||||
|
|
||||||
response = request(t, s, "GET", "/v1/stats", "", nil)
|
response = request(t, s, "GET", "/v1/stats", "", nil)
|
||||||
require.Equal(t, 200, response.Code)
|
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) {
|
func TestServer_MessageHistoryMaxSize(t *testing.T) {
|
||||||
|
|
|
@ -244,8 +244,10 @@ type apiHealthResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiStatsResponse struct {
|
type apiStatsResponse struct {
|
||||||
Messages int64 `json:"messages"`
|
Messages int64 `json:"messages"`
|
||||||
MessagesRate float64 `json:"messages_rate"` // Average number of messages per second
|
MessagesRate float64 `json:"messages_rate"` // Average number of messages per second
|
||||||
|
TotalTopics int64 `json:"total_topics"`
|
||||||
|
TotalSubscriptions int64 `json:"total_subscriptions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiUserAddRequest struct {
|
type apiUserAddRequest struct {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue