diff --git a/_example/chi/go.mod b/_example/chi/go.mod index 2a5fe0da..a896f8fd 100644 --- a/_example/chi/go.mod +++ b/_example/chi/go.mod @@ -3,10 +3,8 @@ module example/chi go 1.19 require ( - github.com/arl/statsviz v0.6.0 + github.com/arl/statsviz v0.0.0 github.com/go-chi/chi v1.5.4 ) -require github.com/gorilla/websocket v1.5.0 // indirect - replace github.com/arl/statsviz => ../../ diff --git a/_example/chi/go.sum b/_example/chi/go.sum index 50ae7391..a713ca02 100644 --- a/_example/chi/go.sum +++ b/_example/chi/go.sum @@ -1,7 +1,5 @@ github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs= github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/_example/chi/main.go b/_example/chi/main.go index 7588cf0e..0222de90 100644 --- a/_example/chi/main.go +++ b/_example/chi/main.go @@ -20,7 +20,7 @@ func main() { // Create a chi router and register statsviz http handlers. r := chi.NewRouter() - r.Get("/debug/statsviz/ws", srv.Ws()) + r.Get("/debug/statsviz/metrics", srv.Metrics()) r.Get("/debug/statsviz", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/debug/statsviz/", 301) }) diff --git a/_example/default/go.mod b/_example/default/go.mod index 453aece7..485612b7 100644 --- a/_example/default/go.mod +++ b/_example/default/go.mod @@ -2,8 +2,6 @@ module example/default go 1.19 -require github.com/arl/statsviz v0.6.0 - -require github.com/gorilla/websocket v1.5.0 // indirect - replace github.com/arl/statsviz => ../../ + +require github.com/arl/statsviz v0.0.0 diff --git a/_example/default/go.sum b/_example/default/go.sum index 94a9e7b9..3be71963 100644 --- a/_example/default/go.sum +++ b/_example/default/go.sum @@ -1,5 +1,3 @@ -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/_example/echo/go.mod b/_example/echo/go.mod index 1676fc2e..cc332dcb 100644 --- a/_example/echo/go.mod +++ b/_example/echo/go.mod @@ -2,20 +2,21 @@ module example/echo go 1.19 +replace github.com/arl/statsviz => ../../ + require ( - github.com/arl/statsviz v0.6.0 + github.com/arl/statsviz v0.0.0 github.com/labstack/echo/v4 v4.11.1 ) require ( - github.com/gorilla/websocket v1.5.0 // indirect github.com/labstack/gommon v0.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sys v0.12.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect ) diff --git a/_example/echo/go.sum b/_example/echo/go.sum index b12a3f93..eb7d64a5 100644 --- a/_example/echo/go.sum +++ b/_example/echo/go.sum @@ -1,10 +1,6 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= @@ -27,17 +23,17 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= diff --git a/_example/fasthttp/go.mod b/_example/fasthttp/go.mod index 57418999..d72c6b44 100644 --- a/_example/fasthttp/go.mod +++ b/_example/fasthttp/go.mod @@ -2,8 +2,10 @@ module example/fasthttp go 1.19 +replace github.com/arl/statsviz => ../../ + require ( - github.com/arl/statsviz v0.6.0 + github.com/arl/statsviz v0.0.0 github.com/fasthttp/router v1.4.12 github.com/soheilhy/cmux v0.1.5 github.com/valyala/fasthttp v1.44.0 @@ -11,10 +13,9 @@ require ( require ( github.com/andybalholm/brotli v1.0.4 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/text v0.13.0 // indirect ) diff --git a/_example/fasthttp/go.sum b/_example/fasthttp/go.sum index 8035897b..6783c3e7 100644 --- a/_example/fasthttp/go.sum +++ b/_example/fasthttp/go.sum @@ -1,12 +1,8 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= github.com/fasthttp/router v1.4.12 h1:QEgK+UKARaC1bAzJgnIhdUMay6nwp+YFq6VGPlyKN1o= github.com/fasthttp/router v1.4.12/go.mod h1:41Qdc4Z4T2pWVVtATHCnoUnOtxdBoeKEYJTXhHwbxCQ= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -29,8 +25,8 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -40,14 +36,14 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= diff --git a/_example/fasthttp/main.go b/_example/fasthttp/main.go index 41615d44..67b9d0c8 100644 --- a/_example/fasthttp/main.go +++ b/_example/fasthttp/main.go @@ -37,7 +37,7 @@ func main() { ws.HandleFunc("/debug/statsviz/ws", srv.Ws()) // Server start - go http.Serve(m.Match(cmux.HTTP1HeaderField("Upgrade", "websocket")), ws) + go http.Serve(m.Match(cmux.HTTP1HeaderField("Accept", "text/event-stream")), ws) go fasthttp.Serve(m.Match(cmux.Any()), r.Handler) fmt.Println("Point your browser to http://localhost:8083/debug/statsviz/") m.Serve() diff --git a/_example/fiber/go.mod b/_example/fiber/go.mod index ece2f1dc..9f8a7d9c 100644 --- a/_example/fiber/go.mod +++ b/_example/fiber/go.mod @@ -2,8 +2,10 @@ module example/fiber go 1.19 +replace github.com/arl/statsviz => ../../ + require ( - github.com/arl/statsviz v0.6.0 + github.com/arl/statsviz v0.0.0 github.com/gofiber/adaptor/v2 v2.2.1 github.com/gofiber/fiber/v2 v2.49.2 github.com/soheilhy/cmux v0.1.5 @@ -12,7 +14,6 @@ require ( require ( github.com/andybalholm/brotli v1.0.5 // indirect github.com/google/uuid v1.3.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect @@ -21,7 +22,7 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.49.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect ) diff --git a/_example/fiber/go.sum b/_example/fiber/go.sum index dee05e80..1b3c395a 100644 --- a/_example/fiber/go.sum +++ b/_example/fiber/go.sum @@ -1,15 +1,11 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= github.com/gofiber/adaptor/v2 v2.2.1 h1:givE7iViQWlsTR4Jh7tB4iXzrlKBgiraB/yTdHs9Lv4= github.com/gofiber/adaptor/v2 v2.2.1/go.mod h1:AhR16dEqs25W2FY/l8gSj1b51Azg5dtPDmm+pruNOrc= github.com/gofiber/fiber/v2 v2.49.2 h1:ONEN3/Vc+dUCxxDgZZwpqvhISgHqb+bu+isBiEyKEQs= github.com/gofiber/fiber/v2 v2.49.2/go.mod h1:gNsKnyrmfEWFpJxQAV0qvW6l70K1dZGno12oLtukcts= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -34,18 +30,18 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= diff --git a/_example/fiber/main.go b/_example/fiber/main.go index 8c57b1b3..2b17079b 100644 --- a/_example/fiber/main.go +++ b/_example/fiber/main.go @@ -43,7 +43,7 @@ func main() { fmt.Println("Point your browser to http://localhost:8093/debug/statsviz/") // Server start - go http.Serve(m.Match(cmux.HTTP1HeaderField("Upgrade", "websocket")), ws) + go http.Serve(m.Match(cmux.HTTP1HeaderField("Accept", "text/event-stream")), ws) go app.Listener(m.Match(cmux.Any())) m.Serve() } diff --git a/_example/gin/go.mod b/_example/gin/go.mod index 430b3b2e..a7fba7ff 100644 --- a/_example/gin/go.mod +++ b/_example/gin/go.mod @@ -2,8 +2,10 @@ module example/gin go 1.19 +replace github.com/arl/statsviz => ../../ + require ( - github.com/arl/statsviz v0.6.0 + github.com/arl/statsviz v0.0.0 github.com/gin-gonic/gin v1.9.1 ) @@ -16,7 +18,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/kr/pretty v0.1.0 // indirect @@ -28,10 +29,10 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/_example/gin/go.sum b/_example/gin/go.sum index f1e0d6e1..70b015fe 100644 --- a/_example/gin/go.sum +++ b/_example/gin/go.sum @@ -1,5 +1,3 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -28,8 +26,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -72,16 +68,16 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/_example/gorilla/go.mod b/_example/gorilla/go.mod index e8a096f6..2eb0877e 100644 --- a/_example/gorilla/go.mod +++ b/_example/gorilla/go.mod @@ -2,9 +2,9 @@ module example/gorilla go 1.19 +replace github.com/arl/statsviz => ../../ + require ( - github.com/arl/statsviz v0.6.0 + github.com/arl/statsviz v0.0.0 github.com/gorilla/mux v1.8.0 ) - -require github.com/gorilla/websocket v1.5.0 // indirect diff --git a/_example/gorilla/go.sum b/_example/gorilla/go.sum index 39fcaf61..8f4b22c3 100644 --- a/_example/gorilla/go.sum +++ b/_example/gorilla/go.sum @@ -1,9 +1,5 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/_example/https/go.mod b/_example/https/go.mod index b5f40557..a4f53681 100644 --- a/_example/https/go.mod +++ b/_example/https/go.mod @@ -2,6 +2,6 @@ module example/https go 1.19 -require github.com/arl/statsviz v0.6.0 +replace github.com/arl/statsviz => ../../ -require github.com/gorilla/websocket v1.5.0 // indirect +require github.com/arl/statsviz v0.0.0 diff --git a/_example/https/go.sum b/_example/https/go.sum index a2737a6f..3be71963 100644 --- a/_example/https/go.sum +++ b/_example/https/go.sum @@ -1,7 +1,3 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/_example/iris/go.mod b/_example/iris/go.mod index 4bf312c8..cd0c2ef1 100644 --- a/_example/iris/go.mod +++ b/_example/iris/go.mod @@ -2,8 +2,10 @@ module example/iris go 1.19 +replace github.com/arl/statsviz => ../../ + require ( - github.com/arl/statsviz v0.6.0 + github.com/arl/statsviz v0.0.0 github.com/kataras/iris/v12 v12.1.8 ) @@ -45,10 +47,10 @@ require ( github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect github.com/yudai/gojsondiff v1.0.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect - golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/_example/iris/go.sum b/_example/iris/go.sum index eea5c3d1..40feacb9 100644 --- a/_example/iris/go.sum +++ b/_example/iris/go.sum @@ -15,8 +15,6 @@ github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= @@ -169,8 +167,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A= -golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -179,8 +177,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -190,20 +188,20 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/_example/middleware/go.mod b/_example/middleware/go.mod index 9c202609..0279d0d9 100644 --- a/_example/middleware/go.mod +++ b/_example/middleware/go.mod @@ -2,6 +2,6 @@ module example/middleware go 1.19 -require github.com/arl/statsviz v0.6.0 +replace github.com/arl/statsviz => ../../ -require github.com/gorilla/websocket v1.5.0 // indirect +require github.com/arl/statsviz v0.0.0 diff --git a/_example/middleware/go.sum b/_example/middleware/go.sum index a2737a6f..3be71963 100644 --- a/_example/middleware/go.sum +++ b/_example/middleware/go.sum @@ -1,7 +1,3 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/_example/mux/go.mod b/_example/mux/go.mod index 32a598e1..6a4f2ccf 100644 --- a/_example/mux/go.mod +++ b/_example/mux/go.mod @@ -2,6 +2,6 @@ module example/mux go 1.19 -require github.com/arl/statsviz v0.6.0 +replace github.com/arl/statsviz => ../../ -require github.com/gorilla/websocket v1.5.0 // indirect +require github.com/arl/statsviz v0.0.0 diff --git a/_example/mux/go.sum b/_example/mux/go.sum index a2737a6f..3be71963 100644 --- a/_example/mux/go.sum +++ b/_example/mux/go.sum @@ -1,7 +1,3 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/_example/options/go.mod b/_example/options/go.mod index 44d87e3b..214a2e07 100644 --- a/_example/options/go.mod +++ b/_example/options/go.mod @@ -2,6 +2,6 @@ module example/options go 1.19 -require github.com/arl/statsviz v0.6.0 +replace github.com/arl/statsviz => ../../ -require github.com/gorilla/websocket v1.5.0 // indirect +require github.com/arl/statsviz v0.0.0 diff --git a/_example/options/go.sum b/_example/options/go.sum index a2737a6f..3be71963 100644 --- a/_example/options/go.sum +++ b/_example/options/go.sum @@ -1,7 +1,3 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/_example/options/main.go b/_example/options/main.go index fc37c61a..1d09abcd 100644 --- a/_example/options/main.go +++ b/_example/options/main.go @@ -20,6 +20,7 @@ func main() { // milliseconds instead of the default of once per second. _ = statsviz.Register(mux, statsviz.Root("/foo/bar"), + statsviz.MetricsPath("foo1/metrics1"), statsviz.SendFrequency(250*time.Millisecond), ) diff --git a/_example/userplots/go.mod b/_example/userplots/go.mod index d8573b3b..485612b7 100644 --- a/_example/userplots/go.mod +++ b/_example/userplots/go.mod @@ -2,6 +2,6 @@ module example/default go 1.19 -require github.com/arl/statsviz v0.6.0 +replace github.com/arl/statsviz => ../../ -require github.com/gorilla/websocket v1.5.0 // indirect +require github.com/arl/statsviz v0.0.0 diff --git a/_example/userplots/go.sum b/_example/userplots/go.sum index a2737a6f..3be71963 100644 --- a/_example/userplots/go.sum +++ b/_example/userplots/go.sum @@ -1,7 +1,3 @@ -github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= -github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= diff --git a/go.mod b/go.mod index b708ce7f..14714e65 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module github.com/arl/statsviz go 1.20 require ( - github.com/gorilla/websocket v1.5.0 github.com/rogpeppe/go-internal v1.11.0 ) require ( - golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect golang.org/x/tools v0.1.12 // indirect ) diff --git a/go.sum b/go.sum index a50c6502..cf245aff 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,10 @@ -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/internal/static/js/app.js b/internal/static/js/app.js index 72ba5b2c..cf8edff5 100644 --- a/internal/static/js/app.js +++ b/internal/static/js/app.js @@ -3,15 +3,6 @@ import * as plot from "./plot.js"; import * as theme from "./theme.js"; import PlotsDef from './plotsdef.js'; -const buildWebsocketURI = () => { - var loc = window.location, - ws_prot = "ws:"; - if (loc.protocol === "https:") { - ws_prot = "wss:"; - } - return ws_prot + "//" + loc.host + loc.pathname + "ws" -} - const dataRetentionSeconds = 600; var timeout = 250; @@ -26,38 +17,44 @@ let paused = false; let show_gc = true; let timerange = 60; -/* WebSocket connection handling */ -const connect = () => { - const uri = buildWebsocketURI(); - let ws = new WebSocket(uri); - console.info(`Attempting websocket connection to server at ${uri}`); - - ws.onopen = () => { +const dataProcessor = { + initDone: false, + close: (e) => {dataProcessor.onclose(e||"connection fail")}, + connected: false, + retrying: false, + onopen: () => { + dataProcessor.initDone = false; + dataProcessor.connected = true; console.info("Successfully connected"); timeout = 250; // reset connection timeout for next time - }; - - ws.onclose = event => { - console.error(`Closed websocket connection: code ${event.code}`); - setTimeout(connect, clamp(timeout += timeout, 250, 5000)); - }; - - ws.onerror = err => { - console.error(`Websocket error, closing connection.`); - ws.close(); - }; - - let initDone = false; - ws.onmessage = event => { + }, + onclose: event => { + dataProcessor.connected = false; + console.error(`Closed connection: code ${event.code || event}`); + if (dataProcessor.retrying) { + return + } + dataProcessor.retrying = true + setTimeout(() => { + connect() + dataProcessor.retrying = false + }, clamp(timeout += timeout, 250, 5000)); + }, + onerror: err => { + console.error(`error, closing connection.`, err); + dataProcessor.close(); + }, + onmessage: event => { let data = JSON.parse(event.data) - - if (!initDone) { + if (!dataProcessor.initDone) { configurePlots(PlotsDef); stats.init(PlotsDef, dataRetentionSeconds); attachPlots(); - $('#play_pause').change(() => { paused = !paused; }); + $('#play_pause').change(() => { + paused = !paused; + }); $('#show_gc').change(() => { show_gc = !show_gc; updatePlots(); @@ -67,17 +64,31 @@ const connect = () => { timerange = val; updatePlots(); }); - initDone = true; - return; + dataProcessor.initDone = true; } - + dataProcessor.onData(data); + }, + onData: data => { stats.pushData(data); - if (paused) { + if (paused || !dataProcessor.connected) { return } - updatePlots(PlotsDef.events); + updatePlots() } } +/* WebSocket connection handling */ +const connect = () => { + + // compatible with the following writing methods + // mux.HandleFunc("/debug/statsviz/ws", srv.Metrics()) + let path = window.location.pathname+(PlotsDef.metricsPath || "ws"); + const eventSource = new EventSource(path); + console.info(`Attempting metrics connection to server at ${path}`); + for (let event in dataProcessor) { + eventSource[event] = dataProcessor[event]; + } + dataProcessor.close = eventSource.close +} connect(); @@ -102,7 +113,20 @@ const attachPlots = () => { } } -const updatePlots = () => { +function throttle(func, delay) { + const context = this; + let timerFlag = null; + return function () { + if (timerFlag === null) { + func.apply(context,arguments); + timerFlag = setTimeout(() => { + timerFlag = null; + }, delay); + } + }; +} + +const updatePlots = throttle(() => { // Create shapes. let shapes = new Map(); @@ -123,7 +147,7 @@ const updatePlots = () => { plot.update(xrange, data, shapes); } }); -} +}, (PlotsDef.sendFrequency || 1000) / 10) const updatePlotsLayout = () => { plots.forEach(plot => { @@ -139,7 +163,7 @@ theme.updateThemeMode(); $('#color_theme_sw').change(() => { const themeMode = theme.getThemeMode(); const newTheme = themeMode === "dark" && "light" || "dark"; - localStorage.setItem("theme-mode", newTheme); + localStorage.setItem("theme-mode", newTheme); theme.updateThemeMode(); updatePlotsLayout(); }); diff --git a/internal/static/js/stats.js b/internal/static/js/stats.js index 5e8c8809..ba938b84 100644 --- a/internal/static/js/stats.js +++ b/internal/static/js/stats.js @@ -92,4 +92,4 @@ const slice = (n) => { return sliced; } -export { init, pushData, slice }; \ No newline at end of file +export { init, pushData, slice }; diff --git a/statsviz.go b/statsviz.go index 1d1cff0d..3f33a091 100644 --- a/statsviz.go +++ b/statsviz.go @@ -32,32 +32,33 @@ // - you want to place Statsviz handler behind some middleware // // then use [NewServer] to obtain a [Server] instance. Both the [Server.Index] and -// [Server.Ws]() methods return [http.HandlerFunc]. +// [Server.Metrics]() methods return [http.HandlerFunc]. // // srv, err := statsviz.NewServer(); // Create server or handle error // srv.Index() // UI (dashboard) http.HandlerFunc -// srv.Ws() // Websocket http.HandlerFunc +// srv.Metrics() // Metrics http.HandlerFunc package statsviz import ( "bytes" "encoding/json" "fmt" + "io" "net/http" "os" "path/filepath" "strconv" "strings" + "sync" "time" - "github.com/gorilla/websocket" - "github.com/arl/statsviz/internal/plot" "github.com/arl/statsviz/internal/static" ) const ( defaultRoot = "/debug/statsviz" + defaultMetrics = "metrics" defaultSendInterval = time.Second ) @@ -82,13 +83,14 @@ func Register(mux *http.ServeMux, opts ...Option) error { // updates metrics data and provides two essential HTTP handlers: // - the Index handler serves Statsviz user interface, allowing you to // visualize runtime metrics on your browser. -// - The Ws handler establishes a WebSocket connection allowing the connected +// - The Metrics handler establishes a data connection allowing the connected // browser to receive metrics updates from the server. // // The zero value is not a valid Server, use NewServer to create a valid one. type Server struct { intv time.Duration // interval between consecutive metrics emission root string // HTTP path root + metrics string // http path for metrics plots *plot.List // plots shown on the user interface userPlots []plot.UserPlot } @@ -101,8 +103,9 @@ type Server struct { // the Index and Ws handlers. func NewServer(opts ...Option) (*Server, error) { s := &Server{ - intv: defaultSendInterval, - root: defaultRoot, + intv: defaultSendInterval, + root: defaultRoot, + metrics: defaultMetrics, } for _, opt := range opts { @@ -143,6 +146,15 @@ func Root(path string) Option { } } +// MetricsPath changes the metrics path of the Statsviz user interface. +// The default is root+"/metrics". +func MetricsPath(path string) Option { + return func(s *Server) error { + s.metrics = path + return nil + } +} + // TimeseriesPlot adds a new time series plot to Statsviz. This options can // be added multiple times. func TimeseriesPlot(tsp TimeSeriesPlot) Option { @@ -155,26 +167,43 @@ func TimeseriesPlot(tsp TimeSeriesPlot) Option { // Register registers the Statsviz HTTP handlers on the provided mux. func (s *Server) Register(mux *http.ServeMux) { mux.Handle(s.root+"/", s.Index()) - mux.HandleFunc(s.root+"/ws", s.Ws()) + if s.metrics == "" { + s.metrics = defaultMetrics + } + mux.HandleFunc(s.root+"/"+s.metrics, s.Metrics()) } // intercept is a middleware that intercepts requests for plotsdef.js, which is // generated dynamically based on the plots configuration. Other requests are // forwarded as-is. -func intercept(h http.Handler, cfg *plot.Config) http.HandlerFunc { - buf := bytes.Buffer{} - buf.WriteString("export default ") - enc := json.NewEncoder(&buf) - enc.SetIndent("", " ") - if err := enc.Encode(cfg); err != nil { - panic("unexpected failure to encode plot definitions: " + err.Error()) +func intercept(h http.Handler, cfg *plot.Config, extraConfig map[string]any) http.HandlerFunc { + var plotsdefjs []byte + //Using parentheses helps gc + { + buf := bytes.Buffer{} + buf.WriteString("export default ") + enc := json.NewEncoder(&buf) + enc.SetIndent("", " ") + var encodeValue any = cfg + if len(extraConfig) > 0 { + encodeValue1 := map[string]any{ + "series": cfg.Series, + "events": cfg.Events, + } + for k, v := range extraConfig { + encodeValue1[k] = v + } + encodeValue = encodeValue1 + } + if err := enc.Encode(encodeValue); err != nil { + panic("unexpected failure to encode plot definitions: " + err.Error()) + } + buf.WriteString(";") + plotsdefjs = buf.Bytes() } - buf.WriteString(";") - plotsdefjs := buf.Bytes() - return func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "js/plotsdef.js" { - w.Header().Add("Content-Length", strconv.Itoa(buf.Len())) + w.Header().Add("Content-Length", strconv.Itoa(len(plotsdefjs))) w.Header().Add("Content-Type", "text/javascript; charset=utf-8") w.Write(plotsdefjs) return @@ -224,60 +253,91 @@ func assetsFS() http.FileSystem { // Index returns the index handler, which responds with the Statsviz user // interface HTML page. By default, the handler is served at the path specified -// by the root. Use [WithRoot] to change the path. +// by the root. The default path is "/debug/statsviz/". Use [Root] to change the path. func (s *Server) Index() http.HandlerFunc { prefix := strings.TrimSuffix(s.root, "/") + "/" assets := http.FileServer(assetsFS()) - handler := intercept(assets, s.plots.Config()) - + // defer initialization until the actual request, so that the Server's properties(s.xxx) are fixed + once := sync.Once{} + var realHandler http.HandlerFunc + handler := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + once.Do(func() { + realHandler = intercept(assets, s.plots.Config(), map[string]any{ + "sendFrequency": s.intv.Milliseconds(), + "metricsPath": s.metrics, + }) + }) + // the sse protocol in github.com/soheilhy/cmux and other frameworks may reuse other requests, + // actively close to avoid bugs. + writer.Header().Add("Connection", "close") + realHandler.ServeHTTP(writer, request) + }) return http.StripPrefix(prefix, handler).ServeHTTP } -// Ws returns the WebSocket handler used by Statsviz to send application -// metrics. The underlying net.Conn is used to upgrade the HTTP server -// connection to the WebSocket protocol. +// Ws returns the long connection handler used by Statsviz to send application metrics. +// The default path is root+"/ws". Use [MetricsPath] to change the path. +// Deprecated: use Metrics instead func (s *Server) Ws() http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var upgrader = websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - } + println("statsviz.Server.Ws() is deprecated, use statsviz.Server.Metrics() instead") + //if you use the websockt version of writing, we will change the default path to ws + if s.metrics == "" || s.metrics == defaultMetrics { + s.metrics = "ws" + } + return s.Metrics() +} - ws, err := upgrader.Upgrade(w, r, nil) - if err != nil { +// Metrics returns the long connection handler used by Statsviz to send application metrics. +// The default path is root+"/metrics". Use [MetricsPath] to change the path. +func (s *Server) Metrics() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if strings.Contains(r.Header.Get("Accept"), "/event-stream") { + // If the connection is initiated by an already open web UI + // (started by a previous process, for example), then plotsdef.js won't be + // requested. Call plots.Config() manually to ensure that s.plots internals + // are correctly initialized. + s.plots.Config() + + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + s.startTransfer(w) return } - defer ws.Close() - - // Ignore this error. This happens when the other end connection closes, - // for example. We can't handle it in any meaningful way anyways. - _ = s.sendStats(ws, s.intv) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("This endpoint only supports text/event-stream requests")) } } -// sendStats sends runtime statistics over the WebSocket connection. -func (s *Server) sendStats(conn *websocket.Conn, frequency time.Duration) error { - tick := time.NewTicker(frequency) - defer tick.Stop() - - // If the WebSocket connection is initiated by an already open web UI - // (started by a previous process, for example), then plotsdef.js won't be - // requested. Call plots.Config() manually to ensure that s.plots internals - // are correctly initialized. - s.plots.Config() - - for range tick.C { - w, err := conn.NextWriter(websocket.TextMessage) - if err != nil { - return err - } - if err := s.plots.WriteValues(w); err != nil { +func (s *Server) startTransfer(w io.Writer) { + buffer := bytes.Buffer{} + callData := func() error { + buffer.WriteString("data: ") + if err := s.plots.WriteValues(&buffer); err == nil { + buffer.WriteByte('\n') + _, err = w.Write(buffer.Bytes()) + if err != nil { + return err + } + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + buffer.Reset() + } else { return err } - if err := w.Close(); err != nil { - return err + return nil + } + //the first time it was sent immediately + err := callData() + if err != nil { + return + } + tick := time.NewTicker(s.intv) + defer tick.Stop() + for range tick.C { + if callData() != nil { + return } } - - panic("unreachable") } diff --git a/statsviz_test.go b/statsviz_test.go index 1e972f45..fb4ac339 100644 --- a/statsviz_test.go +++ b/statsviz_test.go @@ -1,7 +1,9 @@ package statsviz import ( + "bufio" "bytes" + "encoding/json" "io" "io/fs" "net/http" @@ -11,8 +13,6 @@ import ( "testing" "time" - "github.com/gorilla/websocket" - "github.com/arl/statsviz/internal/static" ) @@ -70,13 +70,13 @@ func TestRoot(t *testing.T) { testIndex(t, newServer(t, Root("/test/")).Index(), "http://example.com/test/") } -func testWs(t *testing.T, f http.Handler, URL string) { +func testMetrics(t *testing.T, f http.Handler, URL string) { t.Helper() s := httptest.NewServer(f) defer s.Close() - // Build a "ws://" url using the httptest server URL and the URL argument. + // Build url using the httptest server URL and the URL argument. u1, err := url.Parse(s.URL) if err != nil { t.Fatal(err) @@ -86,15 +86,26 @@ func testWs(t *testing.T, f http.Handler, URL string) { t.Fatal(err) } - u1.Scheme = "ws" u1.Path = u2.Path // Connect to the server - ws, _, err := websocket.DefaultDialer.Dial(u1.String(), nil) if err != nil { t.Fatalf("%v", err) } - defer ws.Close() + request, err := http.NewRequest(http.MethodGet, u1.String(), nil) + request.Header.Set("Accept", "text/event-stream") + resp, err := http.DefaultClient.Do(request) + if err != nil { + t.Fatalf("requset error %v", err) + return + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + t.Fatalf("http status %v, want %v", resp.StatusCode, http.StatusOK) + return + } + //sse data , readline to parse + reader := bufio.NewReader(resp.Body) // Check the content of 2 consecutive payloads. for i := 0; i < 2; i++ { @@ -105,10 +116,22 @@ func testWs(t *testing.T, f http.Handler, URL string) { Goroutines []uint64 `json:"goroutines"` SizeClasses []uint64 `json:"size-classes"` } - if err := ws.ReadJSON(&data); err != nil { - t.Fatalf("failed reading json from websocket: %v", err) + line, prefix, err := reader.ReadLine() + if err != nil { + t.Fatalf("failed reading line from sse: %v", err) + return + } + if prefix { + t.Fatalf("line too long") + return + } + if !bytes.HasPrefix(line, []byte("data: ")) { + i-- + continue + } + if err := json.Unmarshal(line[5:], &data); err != nil { + t.Fatalf("failed reading json from sse: %v", err) } - // The time series must have one and only one element if len(data.Goroutines) != 1 { t.Errorf("len(goroutines) = %d, want 1", len(data.Goroutines)) @@ -120,28 +143,28 @@ func testWs(t *testing.T, f http.Handler, URL string) { } } -func TestWs(t *testing.T) { +func TestMetrics(t *testing.T) { t.Parallel() - testWs(t, newServer(t).Ws(), "http://example.com/debug/statsviz/ws") + testMetrics(t, newServer(t).Metrics(), "http://example.com/debug/statsviz/metrics") } func TestWsCantUpgrade(t *testing.T) { - url := "http://example.com/debug/statsviz/ws" + url := "http://example.com/debug/statsviz/metrics" req := httptest.NewRequest("GET", url, nil) w := httptest.NewRecorder() - newServer(t).Ws()(w, req) + newServer(t).Metrics()(w, req) if w.Result().StatusCode != http.StatusBadRequest { - t.Errorf("responded %v to %q with non-websocket-upgradable conn, want %v", w.Result().StatusCode, url, http.StatusBadRequest) + t.Errorf("responded %v to %q with non-upgradable conn, want %v", w.Result().StatusCode, url, http.StatusBadRequest) } } func testRegister(t *testing.T, f http.Handler, baseURL string) { testIndex(t, f, baseURL) - ws := strings.TrimRight(baseURL, "/") + "/ws" - testWs(t, f, ws) + url := strings.TrimRight(baseURL, "/") + "/metrics" + testMetrics(t, f, url) } func TestRegister(t *testing.T) { @@ -212,7 +235,7 @@ func Test_intercept(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "http://example.com/debug/statsviz/js/plotsdef.js", nil) srv := newServer(t) - intercept(srv.Index(), srv.plots.Config())(w, req) + intercept(srv.Index(), srv.plots.Config(), nil)(w, req) resp := w.Result() if resp.StatusCode != http.StatusOK {