Forráskód Böngészése

Better stats in realtime-advanced

Manu Mtz-Almeida 10 éve
szülő
commit
eed6d93095

+ 0 - 3
examples/realtime-advanced/main.go

@@ -5,11 +5,8 @@ import (
 	"runtime"
 
 	"github.com/gin-gonic/gin"
-	"github.com/manucorporat/stats"
 )
 
-var messages = stats.New()
-
 func main() {
 	ConfigRuntime()
 	StartWorkers()

+ 19 - 13
examples/realtime-advanced/resources/room_login.templ.html

@@ -62,7 +62,7 @@
                 <p>The chat and the charts data is provided in realtime using the SSE implemention of <a href="https://github.com/gin-gonic/gin/blob/15b0c49da556d58a3d934b86e3aa552ff224026d/examples/realtime-chat/main.go#L23-L32">Gin Framework</a>.</p>
                 <div class="row">
                     <div class="col-md-8">
-                        <div id="chat-scroll" style="overflow-y:scroll; overflow-x:scroll; height:270px">
+                        <div id="chat-scroll" style="overflow-y:scroll; overflow-x:scroll; height:290px">
                             <table id="table-style" class="table" data-show-header="false">
                                 <thead>
                                     <tr>
@@ -97,8 +97,12 @@
                         {{end}}
                     </div>
                     <div class="col-md-4">
-                        <h3>Inbound/Outbound</h3>
-                        <div id="messagesChart" class="epoch category20c"></div>
+                        <div id="messagesChart" class="epoch category10"></div>
+                        <p>
+                        <span style="font-size:20px; color:#1f77b4">◼︎</span> Users<br>
+                        <span style="font-size:20px; color:#ff7f0e">◼︎</span> Inbound messages / sec<br>
+                        <span style="font-size:20px; color:#2ca02c">◼︎</span> Outbound messages / sec<br>
+                        </p>
                     </div>
                 </div>
             </div>
@@ -106,22 +110,24 @@
         <div class="container">
             <div class="row">
                 <h2>Realtime server Go stats</h2>
-                <div class="col-md-4">
-                    <h3>Number of Goroutines</h3>
+                <div class="col-md-6">
+                    <h3>Memory usage</h3>
                     <p>
-                    <div id="goroutinesChart" class="epoch category20c"></div>
+                    <div id="heapChart" class="epoch category20c"></div>
                     </p>
-                </div>
-                <div class="col-md-4">
-                    <h3>HEAP/Stack bytes</h3>
                     <p>
-                    <div id="heapChart" class="epoch category20b"></div>
+                    <span style="font-size:20px; color:#1f77b4">◼︎</span> Heap bytes<br>
+                    <span style="font-size:20px; color:#aec7e8">◼︎</span> Stack bytes<br>
                     </p>
                 </div>
-                <div class="col-md-4">
-                    <h3>Mallocs/Frees</h3>
+                <div class="col-md-6">
+                    <h3>Allocations per second</h3>
+                    <p>
+                    <div id="mallocsChart" class="epoch category20b"></div>
+                    </p>
                     <p>
-                    <div id="mallocsChart" class="epoch category10"></div>
+                    <span style="font-size:20px; color:#393b79">◼︎</span> Mallocs / sec<br>
+                    <span style="font-size:20px; color:#5254a3">◼︎</span> Frees / sec<br>
                     </p>
                 </div>
             </div>

+ 12 - 19
examples/realtime-advanced/resources/static/realtime.js

@@ -18,19 +18,12 @@ function StartEpoch(timestamp) {
     var windowSize = 60;
     var height = 200;
     var defaultData = histogram(windowSize, timestamp);
-    window.goroutinesChart = $('#goroutinesChart').epoch({
-        type: 'time.bar',
-        axes: ['bottom', 'left'],
-        height: height,
-        data: [
-            {values: defaultData}
-        ]
-    });
 
     window.heapChart = $('#heapChart').epoch({
         type: 'time.area',
         axes: ['bottom', 'left'],
         height: height,
+        historySize: 10,
         data: [
             {values: defaultData},
             {values: defaultData}
@@ -41,6 +34,7 @@ function StartEpoch(timestamp) {
         type: 'time.area',
         axes: ['bottom', 'left'],
         height: height,
+        historySize: 10,
         data: [
             {values: defaultData},
             {values: defaultData}
@@ -48,10 +42,12 @@ function StartEpoch(timestamp) {
     });
 
     window.messagesChart = $('#messagesChart').epoch({
-        type: 'time.area',
+        type: 'time.line',
         axes: ['bottom', 'left'],
-        height: 250,
+        height: 240,
+        historySize: 10,
         data: [
+            {values: defaultData},
             {values: defaultData},
             {values: defaultData}
         ]
@@ -69,11 +65,10 @@ function StartSSE(roomid) {
 }
 
 function stats(e) {
-    var data = parseJSONStats(e.data)
-    heapChart.push(data.heap)
-    mallocsChart.push(data.mallocs)
-    goroutinesChart.push(data.goroutines)
-    messagesChart.push(data.messages)
+    var data = parseJSONStats(e.data);
+    heapChart.push(data.heap);
+    mallocsChart.push(data.mallocs);
+    messagesChart.push(data.messages);
 }
 
 function parseJSONStats(e) {
@@ -90,16 +85,14 @@ function parseJSONStats(e) {
         {time: timestamp, y: data.Frees}
     ];
     var messages = [
+        {time: timestamp, y: data.Connected},
         {time: timestamp, y: data.Inbound},
         {time: timestamp, y: data.Outbound}
     ];
-    var goroutines = [
-        {time: timestamp, y: data.NuGoroutines},
-    ]
+
     return {
         heap: heap,
         mallocs: mallocs,
-        goroutines: goroutines,
         messages: messages
     }
 }

+ 6 - 2
examples/realtime-advanced/routes.go

@@ -59,8 +59,12 @@ func streamRoom(c *gin.Context) {
 	roomid := c.ParamValue("roomid")
 	listener := openListener(roomid)
 	ticker := time.NewTicker(1 * time.Second)
-	defer closeListener(roomid, listener)
-	defer ticker.Stop()
+	users.Add("connected", 1)
+	defer func() {
+		closeListener(roomid, listener)
+		ticker.Stop()
+		users.Add("disconnected", 1)
+	}()
 
 	c.Stream(func(w io.Writer) bool {
 		select {

+ 24 - 8
examples/realtime-advanced/stats.go

@@ -4,33 +4,49 @@ import (
 	"runtime"
 	"sync"
 	"time"
+
+	"github.com/manucorporat/stats"
 )
 
+var messages = stats.New()
+var users = stats.New()
 var mutexStats sync.RWMutex
 var savedStats map[string]uint64
 
 func statsWorker() {
 	c := time.Tick(1 * time.Second)
+	var lastMallocs uint64 = 0
+	var lastFrees uint64 = 0
 	for range c {
 		var stats runtime.MemStats
 		runtime.ReadMemStats(&stats)
 
 		mutexStats.Lock()
 		savedStats = map[string]uint64{
-			"timestamp":    uint64(time.Now().Unix()),
-			"HeapInuse":    stats.HeapInuse,
-			"StackInuse":   stats.StackInuse,
-			"NuGoroutines": uint64(runtime.NumGoroutine()),
-			"Mallocs":      stats.Mallocs,
-			"Frees":        stats.Mallocs,
-			"Inbound":      uint64(messages.Get("inbound")),
-			"Outbound":     uint64(messages.Get("outbound")),
+			"timestamp":  uint64(time.Now().Unix()),
+			"HeapInuse":  stats.HeapInuse,
+			"StackInuse": stats.StackInuse,
+			"Mallocs":    (stats.Mallocs - lastMallocs),
+			"Frees":      (stats.Frees - lastFrees),
+			"Inbound":    uint64(messages.Get("inbound")),
+			"Outbound":   uint64(messages.Get("outbound")),
+			"Connected":  connectedUsers(),
 		}
+		lastMallocs = stats.Mallocs
+		lastFrees = stats.Frees
 		messages.Reset()
 		mutexStats.Unlock()
 	}
 }
 
+func connectedUsers() uint64 {
+	connected := users.Get("connected") - users.Get("disconnected")
+	if connected < 0 {
+		return 0
+	}
+	return uint64(connected)
+}
+
 func Stats() map[string]uint64 {
 	mutexStats.RLock()
 	defer mutexStats.RUnlock()