9 Commits

Author SHA1 Message Date
Adrian Zuercher
8ca441cc24 add optional endpoint to new client 2025-08-24 21:22:11 +02:00
Adrian Zuercher
567d2fe03d add optional endpoint to new client 2025-08-24 21:18:43 +02:00
Adrian Zuercher
756985882a remove memory and garbage collection infos 2025-08-24 08:33:25 +02:00
Adrian Zuercher
bcb271ea3e change package name to repo name 2025-08-24 08:12:25 +02:00
Adrian Zuercher
9cea173185 remove log file 2025-08-24 08:02:35 +02:00
Adrian Zuercher
59423a7432 new pubsub with wildcard option 2025-08-24 07:59:50 +02:00
f96bd0822e test/statusServer.log gelöscht 2025-08-24 07:57:48 +02:00
Adrian Zuercher
7b1d089cc7 add .gitignore 2025-08-23 22:25:39 +02:00
4bb224c8fc .DS_Store gelöscht 2025-08-23 22:24:04 +02:00
11 changed files with 28 additions and 380 deletions

BIN
.DS_Store vendored

Binary file not shown.

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.DS_Store
*.log

4
go.mod
View File

@@ -1,9 +1,9 @@
module statusServer
module gitea.tecamino.com/paadi/statusServer
go 1.24.0
require (
gitea.tecamino.com/paadi/pubSub v1.0.1
gitea.tecamino.com/paadi/pubSub v1.0.2
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1
gitea.tecamino.com/paadi/tecamino-json_data v0.1.0
gitea.tecamino.com/paadi/tecamino-logger v0.2.1

4
go.sum
View File

@@ -1,5 +1,5 @@
gitea.tecamino.com/paadi/pubSub v1.0.1 h1:Of91JAVaiaqXhzFjm+jwSJipPbST+A1WQz1DEEhLQm4=
gitea.tecamino.com/paadi/pubSub v1.0.1/go.mod h1:SBPTSD/JQWRbwqsSNoSPhV81IDTreP0TMyvLhmK3P2M=
gitea.tecamino.com/paadi/pubSub v1.0.2 h1:9Q9KLTIHRSjxrTkDyuF8mDYOLkI8DjjPNSnoS2GKflY=
gitea.tecamino.com/paadi/pubSub v1.0.2/go.mod h1:SBPTSD/JQWRbwqsSNoSPhV81IDTreP0TMyvLhmK3P2M=
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1 h1:vAq7mwUxlxJuLzCQSDMrZCwo8ky5usWi9Qz+UP+WnkI=
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1/go.mod h1:+tmf1rjPaKEoNeUcr1vdtoFIFweNG3aUGevDAl3NMBk=
gitea.tecamino.com/paadi/tecamino-json_data v0.1.0 h1:zp3L8qUvkVqzuesQdMh/SgZZZbX3pGD9NYa6jtz+JvA=

View File

@@ -3,9 +3,10 @@ package handlers
import (
"encoding/json"
"fmt"
"statusServer/models"
"sync"
"gitea.tecamino.com/paadi/statusServer/models"
json_dataModels "gitea.tecamino.com/paadi/tecamino-json_data/models"
"github.com/gin-gonic/gin"

View File

@@ -57,8 +57,11 @@ var upgrader = websocket.Upgrader{
EnableCompression: false,
}
func NewClient(ip, id string, port uint, logger *logging.Logger) (*Client, error) {
u := url.URL{Scheme: "ws", Host: fmt.Sprintf("%s:%d", ip, port), Path: "status", RawQuery: "id=" + id}
func NewClient(id, ip, endpoint string, port uint, logger *logging.Logger) (*Client, error) {
if endpoint == "" {
endpoint = "status"
}
u := url.URL{Scheme: "ws", Host: fmt.Sprintf("%s:%d", ip, port), Path: endpoint, RawQuery: "id=" + id}
c := &Client{
id: id,

View File

@@ -3,7 +3,8 @@ package statusServer
import (
"encoding/json"
"fmt"
"statusServer/models"
"gitea.tecamino.com/paadi/statusServer/models"
pubSubModels "gitea.tecamino.com/paadi/pubSub/models"
logging "gitea.tecamino.com/paadi/tecamino-logger/logging"
@@ -23,7 +24,7 @@ type StatusClient struct {
// serviceName: unique ID/name for this client
// ip, port: target server address
// debug: enable debug logging
func NewStatusClient(serviceName, ip string, port uint, debug bool) (*StatusClient, error) {
func NewStatusClient(serviceName, ip, endpoint string, port uint, debug bool) (*StatusClient, error) {
config := models.Config{Log: logging.Config{Debug: debug}}
config.Default()
@@ -42,7 +43,7 @@ func NewStatusClient(serviceName, ip string, port uint, debug bool) (*StatusClie
}
// connect underlying websocket client
sc.client, err = models.NewClient(ip, serviceName, port, logger)
sc.client, err = models.NewClient(serviceName, ip, endpoint, port, logger)
if err != nil {
return nil, err
}

View File

@@ -1,15 +1,14 @@
package statusServer
import (
"context"
"fmt"
"net/http"
"runtime"
"statusServer/utils"
"strings"
"time"
"statusServer/models"
"gitea.tecamino.com/paadi/statusServer/utils"
"gitea.tecamino.com/paadi/statusServer/models"
logging "gitea.tecamino.com/paadi/tecamino-logger/logging"
"github.com/gin-contrib/cors"
@@ -96,56 +95,12 @@ func NewStatusServer(config models.Config) (*StatusServer, error) {
return s, nil
}
// ServeHttp starts the HTTP server and continuously publishes runtime metrics
// (memory allocation + GC count) to the "info" topic.
//
// ServeHttp starts the HTTP server
// It blocks until the HTTP server stops. Resources are cleaned up on shutdown:
// PubSub is closed and a shutdown message is logged.
func (s *StatusServer) ServeHttp() error {
s.log.Debug("ServeHttp", "start publishing runtime metrics (memory + GC count)")
// create cancellable context for metrics goroutine
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// metrics publisher goroutine
go func() {
for {
var init bool
var m runtime.MemStats
var oldM uint64
var oldGc uint32
var info struct {
Memory uint64 `json:"memory"`
GC uint32 `json:"gc"`
}
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
// stop publishing if context is canceled
return
case <-ticker.C:
// read runtime memory statistics
runtime.ReadMemStats(&m)
info.GC = m.NumGC
// publish only when values changed or first run
if oldGc != m.NumGC || oldM != m.Alloc/1024 || !init {
info.Memory = m.Alloc / 1024
s.pubSub.Publish("info", info)
oldGc = m.NumGC
oldM = m.Alloc / 1024
init = true
}
}
}
}
}()
// log startup
s.log.Info("ServeHttp", fmt.Sprintf("start listening on %s:%d", s.Ip, s.Port))

View File

@@ -2,7 +2,8 @@ package statusServer
import (
"fmt"
"statusServer/handlers"
"gitea.tecamino.com/paadi/statusServer/handlers"
logging "gitea.tecamino.com/paadi/tecamino-logger/logging"
"github.com/gin-gonic/gin"

View File

@@ -1,11 +1,12 @@
package test
import (
"statusServer"
"statusServer/models"
"testing"
"time"
"gitea.tecamino.com/paadi/statusServer"
"gitea.tecamino.com/paadi/statusServer/models"
"gitea.tecamino.com/paadi/tecamino-logger/logging"
)
@@ -34,11 +35,11 @@ func TestConnection(t *testing.T) {
time.Sleep(time.Second)
client1, err := statusServer.NewStatusClient("adrian", "127.0.0.1", 8080, true)
client1, err := statusServer.NewStatusClient("adrian", "127.0.0.1", "", 8080, true)
if err != nil {
t.Fatal(err)
}
client, err := statusServer.NewStatusClient("test", "127.0.0.1", 8080, true)
client, err := statusServer.NewStatusClient("test", "127.0.0.1", "", 8080, true)
if err != nil {
t.Fatal(err)
}

View File

@@ -1,316 +0,0 @@
{"level":"info","timestamp":"2025-08-23T10:24:46.703","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T10:26:29.040","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T10:26:29.040","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T10:26:29.040","msg":"initialize new PubSub service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T10:26:29.040","msg":"start example variables like memory usage and garbage collection count","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T10:26:29.040","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T10:26:29.041","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.041","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.043","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.043","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.043","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.043","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T10:26:30.043","msg":"id:adrian connected to 127.0.0.1:8080","caller":"Client"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.043","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.044","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.044","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.044","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:26:30.044","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:36.617","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T10:28:36.618","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T10:28:36.618","msg":"initialize new PubSub service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T10:28:36.618","msg":"start example variables like memory usage and garbage collection count","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T10:28:36.618","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T10:28:36.619","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.619","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.621","msg":"authorization id token: adrian","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.622","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.622","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.622","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.622","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.622","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.622","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.623","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.623","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.623","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.623","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T10:28:37.624","msg":"subscribe id:adrian topic:test/info","caller":"Websocket"}
{"level":"info","timestamp":"2025-08-23T20:48:20.110","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:48:20.110","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:48:20.111","msg":"initialize new status server server","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:48:20.111","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:48:20.111","msg":"start example variables like memory usage and garbage collection count","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:48:20.111","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:48:20.111","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.111","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.114","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:48:21.115","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:32.958","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:54:32.958","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:54:32.959","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:54:32.959","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:54:32.959","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:54:32.960","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.960","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T20:54:33.961","msg":"id:adrian connected to 127.0.0.1:8080","caller":"Client"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:33.961","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:52.574","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:54:52.574","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:54:52.575","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:54:52.575","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:54:52.575","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:54:52.575","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.311","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.576","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.577","msg":"authorization id token: adrian","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.577","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.577","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.577","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.577","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.577","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:54:53.577","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:00.048","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:55:00.048","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:55:00.049","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:55:00.049","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:55:00.049","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:55:00.049","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.050","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.052","msg":"authorization id token: adrian","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.052","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.052","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.052","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.052","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T20:55:01.052","msg":"id:adrian connected to 127.0.0.1:8080","caller":"Client"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.052","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.053","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.053","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.053","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.053","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.053","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:01.053","msg":"subscribe id:adrian topic:test/info","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:02.176","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:04.610","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:05.111","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:05.391","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:06.443","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:07.210","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:08.226","msg":"authorization id token: test","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:55:47.859","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:55:47.859","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:55:47.859","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:55:47.860","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:55:47.860","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:55:47.860","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.860","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.862","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.862","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.862","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.862","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.862","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.863","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.863","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.863","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:55:48.863","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T20:55:48.863","msg":"id:test connected to 127.0.0.1:8080","caller":"Client"}
{"level":"error","timestamp":"2025-08-23T20:56:05.391","msg":"error on websocket connection: read error (id:test34): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:56:39.215","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:56:39.215","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:56:39.215","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:56:39.216","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:56:39.216","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:56:39.216","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.216","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.218","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.218","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.218","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.218","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T20:56:40.218","msg":"id:adrian connected to 127.0.0.1:8080","caller":"Client"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.218","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.219","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.219","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.219","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:56:40.219","msg":"start write goroutine","caller":"NewClient"}
{"level":"error","timestamp":"2025-08-23T20:56:40.877","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:42.110","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:43.644","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:48.094","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:48.545","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:49.027","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:58.724","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:59.092","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:59.292","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:59.424","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:56:59.608","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:57:00.443","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:57:00.626","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:57:00.809","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:57:00.991","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:57:01.157","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:58:03.738","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:58:03.739","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:58:03.739","msg":"initialize new PubSub service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:58:03.739","msg":"start example variables like memory usage and garbage collection count","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:58:03.739","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:58:03.740","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.740","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.741","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.741","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.741","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.741","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.741","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.742","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.742","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.742","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:04.742","msg":"start write goroutine","caller":"NewClient"}
{"level":"error","timestamp":"2025-08-23T20:58:05.278","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:58:06.860","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:58:10.226","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:58:10.994","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:58:11.561","msg":"error GetIDFromQuery: id missing","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:58:47.241","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:58:47.241","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:58:47.242","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:58:47.242","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:58:47.242","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:58:47.242","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.242","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.244","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.245","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.245","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.245","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.245","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.246","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.246","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.246","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:58:48.246","msg":"start write goroutine","caller":"NewClient"}
{"level":"error","timestamp":"2025-08-23T20:59:02.224","msg":"read json: invalid character '\\n' in string literal","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T20:59:46.456","msg":"error on websocket connection: read error (id:234): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T20:59:58.891","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T20:59:58.891","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:59:58.892","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T20:59:58.892","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:59:58.892","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T20:59:58.892","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.893","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.895","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.895","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.895","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.895","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T20:59:59.895","msg":"id:adrian connected to 127.0.0.1:8080","caller":"Client"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.895","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.896","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.896","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.896","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T20:59:59.896","msg":"start write goroutine","caller":"NewClient"}
{"level":"error","timestamp":"2025-08-23T21:00:06.689","msg":"error on websocket connection: read error (id:234): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T21:00:52.670","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T21:00:52.670","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:00:52.671","msg":"initialize new PubSub service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T21:00:52.671","msg":"start example variables like memory usage and garbage collection count","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:00:52.671","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:00:52.671","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.671","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.674","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.674","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.674","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.674","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.674","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.675","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.675","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.675","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:00:53.675","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T21:00:53.675","msg":"id:test connected to 127.0.0.1:8080","caller":"Client"}
{"level":"error","timestamp":"2025-08-23T21:01:01.672","msg":"error on websocket connection: read error (id:234): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T21:02:03.657","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T21:02:03.657","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:02:03.658","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T21:02:03.658","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:02:03.658","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:02:03.659","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.659","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:02:04.661","msg":"start write goroutine","caller":"NewClient"}
{"level":"error","timestamp":"2025-08-23T21:02:13.655","msg":"error on websocket connection: read error (id:235): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T21:07:39.871","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T21:07:39.871","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:07:39.872","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T21:07:39.872","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:07:39.872","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:07:39.872","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.872","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.874","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.874","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.874","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.874","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.874","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.875","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.875","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.875","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:07:40.875","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T21:07:40.875","msg":"id:test connected to 127.0.0.1:8080","caller":"Client"}
{"level":"error","timestamp":"2025-08-23T21:07:48.105","msg":"error on websocket connection: read error (id:235): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T21:08:02.336","msg":"error on websocket connection: read error (id:235): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T21:08:10.976","msg":"error on websocket connection: websocket: close sent","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T21:08:17.158","msg":"error on websocket connection: websocket: close sent","caller":"Websocket"}
{"level":"debug","timestamp":"2025-08-23T21:39:47.673","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T21:39:47.673","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:39:47.674","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T21:39:47.674","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:39:47.674","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:39:47.674","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.674","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.676","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.676","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.676","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.676","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.676","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.677","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.677","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.677","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:39:48.677","msg":"start write goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:24.365","msg":"initialize new server with allowOrigins: * listening on port: 8080","caller":"NewStatusServer"}
{"level":"info","timestamp":"2025-08-23T21:41:24.365","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:41:24.365","msg":"initialize new PubSubWebsocket service with 5 workers 256 messages","caller":"NewStatusServer"}
{"level":"debug","timestamp":"2025-08-23T21:41:24.365","msg":"start publishing runtime metrics (memory + GC count)","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:41:24.365","msg":"start listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"info","timestamp":"2025-08-23T21:41:24.366","msg":"close server listening on 0.0.0.0:8080","caller":"ServeHttp"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.366","msg":"initialize new client id:adrian to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.368","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.368","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.368","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.368","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T21:41:25.368","msg":"id:adrian connected to 127.0.0.1:8080","caller":"Client"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.368","msg":"initialize new client id:test to 127.0.0.1:8080","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.369","msg":"set PingHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.369","msg":"set PongHandler","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.369","msg":"start read goroutine","caller":"NewClient"}
{"level":"debug","timestamp":"2025-08-23T21:41:25.369","msg":"start write goroutine","caller":"NewClient"}
{"level":"info","timestamp":"2025-08-23T21:41:25.369","msg":"id:test connected to 127.0.0.1:8080","caller":"Client"}
{"level":"error","timestamp":"2025-08-23T21:42:15.297","msg":"error on websocket connection: read error (id:238): websocket: close 1000 (normal)","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T21:42:25.420","msg":"error on websocket connection: websocket: close sent","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T21:42:26.597","msg":"error on websocket connection: read error (id:234): websocket: close 1006 (abnormal closure): unexpected EOF","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T21:42:26.597","msg":"error on websocket connection: read error (id:238): websocket: close 1006 (abnormal closure): unexpected EOF","caller":"Websocket"}
{"level":"error","timestamp":"2025-08-23T21:42:27.701","msg":"error on websocket connection: websocket: close sent","caller":"Websocket"}