-
Number of Goroutines
+
+
Memory usage
-
+
+
+
+ ◼︎ Heap bytes
+ ◼︎ Stack bytes
-
-
HEAP/Stack bytes
+
+
Allocations per second
-
+
-
-
-
Mallocs/Frees
-
+
◼︎ Mallocs / sec
+
◼︎ Frees / sec
diff --git a/examples/realtime-advanced/resources/static/realtime.js b/examples/realtime-advanced/resources/static/realtime.js
index da4ae88c..919dae26 100644
--- a/examples/realtime-advanced/resources/static/realtime.js
+++ b/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
}
}
diff --git a/examples/realtime-advanced/routes.go b/examples/realtime-advanced/routes.go
index 9762f52c..fb1f5b6e 100644
--- a/examples/realtime-advanced/routes.go
+++ b/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 {
diff --git a/examples/realtime-advanced/stats.go b/examples/realtime-advanced/stats.go
index f3ccab38..896787f9 100644
--- a/examples/realtime-advanced/stats.go
+++ b/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()