diff --git a/controllers/serverConfig.go b/controllers/admin/serverConfig.go similarity index 98% rename from controllers/serverConfig.go rename to controllers/admin/serverConfig.go index bfc7bb36c..39771314c 100644 --- a/controllers/serverConfig.go +++ b/controllers/admin/serverConfig.go @@ -1,4 +1,4 @@ -package controllers +package admin import ( "encoding/json" diff --git a/controllers/admin/viewers.go b/controllers/admin/viewers.go new file mode 100644 index 000000000..fe88e59a5 --- /dev/null +++ b/controllers/admin/viewers.go @@ -0,0 +1,15 @@ +package admin + +import ( + "encoding/json" + "net/http" + + "github.com/gabek/owncast/metrics" +) + +// GetViewersOverTime will return the number of viewers at points in time +func GetViewersOverTime(w http.ResponseWriter, r *http.Request) { + viewersOverTime := metrics.Metrics.Viewers + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(viewersOverTime) +} diff --git a/metrics/alerting.go b/metrics/alerting.go index 15a79a9cd..b8e7107d0 100644 --- a/metrics/alerting.go +++ b/metrics/alerting.go @@ -36,6 +36,6 @@ func handleRAMAlerting() { } } -func recentAverage(values []value) int { +func recentAverage(values []timestampedValue) int { return int((values[len(values)-1].Value + values[len(values)-2].Value) / 2) } diff --git a/metrics/hardware.go b/metrics/hardware.go index 7c0f9b8ae..4c0687c21 100644 --- a/metrics/hardware.go +++ b/metrics/hardware.go @@ -20,7 +20,7 @@ func collectCPUUtilization() { panic(err) } - metricValue := value{time.Now(), int(v[0])} + metricValue := timestampedValue{time.Now(), int(v[0])} Metrics.CPUUtilizations = append(Metrics.CPUUtilizations, metricValue) } @@ -30,6 +30,6 @@ func collectRAMUtilization() { } memoryUsage, _ := mem.VirtualMemory() - metricValue := value{time.Now(), int(memoryUsage.UsedPercent)} + metricValue := timestampedValue{time.Now(), int(memoryUsage.UsedPercent)} Metrics.RAMUtilizations = append(Metrics.RAMUtilizations, metricValue) } diff --git a/metrics/metrics.go b/metrics/metrics.go index 210fe92b7..4c00594b7 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -7,14 +7,10 @@ import ( // How often we poll for updates const metricsPollingInterval = 15 * time.Second -type value struct { - Time time.Time - Value int -} - type metrics struct { - CPUUtilizations []value - RAMUtilizations []value + CPUUtilizations []timestampedValue + RAMUtilizations []timestampedValue + Viewers []timestampedValue } // Metrics is the shared Metrics instance @@ -23,6 +19,7 @@ var Metrics *metrics // Start will begin the metrics collection and alerting func Start() { Metrics = new(metrics) + startViewerCollectionMetrics() for range time.Tick(metricsPollingInterval) { handlePolling() diff --git a/metrics/timestampedValue.go b/metrics/timestampedValue.go new file mode 100644 index 000000000..35e560141 --- /dev/null +++ b/metrics/timestampedValue.go @@ -0,0 +1,8 @@ +package metrics + +import "time" + +type timestampedValue struct { + Time time.Time `json:"time"` + Value int `json:"value"` +} diff --git a/metrics/viewers.go b/metrics/viewers.go new file mode 100644 index 000000000..6acc0abc5 --- /dev/null +++ b/metrics/viewers.go @@ -0,0 +1,31 @@ +package metrics + +import ( + "time" + + "github.com/gabek/owncast/core" +) + +// How often we poll for updates +const viewerMetricsPollingInterval = 5 * time.Minute + +func startViewerCollectionMetrics() { + collectViewerCount() + + for range time.Tick(viewerMetricsPollingInterval) { + collectViewerCount() + } +} + +func collectViewerCount() { + if len(Metrics.Viewers) > maxCollectionValues { + Metrics.Viewers = Metrics.Viewers[1:] + } + + count := core.GetStatus().ViewerCount + value := timestampedValue{ + Value: count, + Time: time.Now(), + } + Metrics.Viewers = append(Metrics.Viewers, value) +} diff --git a/router/router.go b/router/router.go index f80c81599..cf1ec759d 100644 --- a/router/router.go +++ b/router/router.go @@ -58,7 +58,10 @@ func Start() error { http.HandleFunc("/api/admin/changekey", middleware.RequireAdminAuth(admin.ChangeStreamKey)) // Server config - http.HandleFunc("/api/admin/serverconfig", middleware.RequireAdminAuth(controllers.GetServerConfig)) + http.HandleFunc("/api/admin/serverconfig", middleware.RequireAdminAuth(admin.GetServerConfig)) + + // Get viewer count over time + http.HandleFunc("/api/admin/viewersOverTime", middleware.RequireAdminAuth(admin.GetViewersOverTime)) port := config.Config.GetPublicWebServerPort()