Git Product home page Git Product logo

statsviz's Introduction

go.dev reference Latest tag Mentioned in Awesome Go

Test Actions Status Test Actions Status codecov

Statsviz

Statsviz Gopher Logo statsviz ui


Visualize real time plots of your Go program runtime metrics, including heap, objects, goroutines, GC pauses, scheduler and more, in your browser.


Install

Download the latest version:

go get github.com/arl/statsviz@latest

Please note that, as new metrics are added to the /runtime/metrics package, new plots are added to Statsviz. This also means that the presence of some plots on the dashboard depends on the Go version you're using.

When in doubt, use the latest ;-)

Usage

Register Statsviz HTTP handlers with your application http.ServeMux.

mux := http.NewServeMux()
statsviz.Register(mux)

go func() {
    log.Println(http.ListenAndServe("localhost:8080", mux))
}()

Open your browser at http://localhost:8080/debug/statsviz

Advanced Usage

If you want more control over Statsviz HTTP handlers, examples are:

  • you're using some HTTP framework
  • you want to place Statsviz handler behind some middleware

then use statsviz.NewServer to obtain a Server instance. Both the Index() and Ws() methods return http.HandlerFunc.

srv, err := statsviz.NewServer(); // Create server or handle error
srv.Index()                       // UI (dashboard) http.HandlerFunc
srv.Ws()                          // Websocket http.HandlerFunc

Please look at examples of usage in the Examples directory.

How Does That Work?

statsviz.Register registers 2 HTTP handlers within the given http.ServeMux:

  • the Index handler serves Statsviz user interface at /debug/statsviz at the address served by your program.

  • The Ws serves a Websocket endpoint. When the browser connects to that endpoint, runtime/metrics are sent to the browser, once per second.

Data points are in a browser-side circular-buffer.

Documentation

Go API

Check out the API reference on pkg.go.dev.

User interface

Controls at the top of the page act on all plots:

menu

  • the groom shows/hides the vertical lines representing garbage collections.
  • the time range selector defines the visualized time span.
  • the play/pause icons stops and resume the refresh of the plots.
  • the light/dark selector switches between light and dark modes.

On top of each plot there are 2 icons:

menu

  • the camera downloads a PNG image of the plot.
  • the info icon shows details about the metrics displayed.

Plots

Depending on your go version, some plots may not be available.

Heap (global)

heap-global

Heap (details)

heap-details

Live Objects in Heap

live-objects

Live Bytes in Heap

live-bytes

MSpan/MCache

mspan-mcache

Memory classes

memory-classes

Goroutines

goroutines

Size Classes

size-classes

GC Scan

gc-scan

GC Cycles

gc-cycles

Stop-the-world Pause Latencies

gc-pauses

CPU Classes (GC)

cpu-classes-gc

Time Goroutines Spend in 'Runnable' state

runnable-time

Time Goroutines Spend Blocked on Mutexes

mutex-wait

Starting Size of Goroutines Stacks

gc-stack-size

Goroutine Scheduling Events

sched-events

CGO Calls

cgo

User Plots

Since v0.6 you can add your own plots to Statsviz dashboard, in order to easily visualize your application metrics next to runtime metrics.

Please see the userplots example.

Examples

Check out the _example directory to see various ways to use Statsviz, such as:

  • use of http.DefaultServeMux or your own http.ServeMux
  • wrap HTTP handler behind a middleware
  • register the web page at /foo/bar instead of /debug/statsviz
  • use https:// rather than http://
  • register Statsviz handlers with various Go HTTP libraries/frameworks:

Questions / Troubleshooting

Either use GitHub's discussions or come to say hi and ask a live question on #statsviz channel on Gopher's slack.

Contributing

Please use issues for bugs and feature requests.
Pull-requests are always welcome!
More details in CONTRIBUTING.md.

Changelog

See CHANGELOG.md.

License: MIT

See LICENSE

statsviz's People

Contributors

arl avatar diendv96 avatar dnnnvx avatar ptxmac avatar shoshinnikita avatar testwill avatar tobias-kuendig avatar tommyblue avatar yehan2002 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

statsviz's Issues

Usage with fasthttp?

Is it somehow possible to use this package with fasthttp as HTTP wrapper in combination with fasthttp-routing?

Because I really like the project and really want to integrate it into one of my projects which bases on these packages.

[Question] Custom metrics implementation questions

Custom metrics is now easier after new released #75.
But it seems that custom metrics like cpu, memory, io and network etc. must be implemented only inside statsviz's plot package which would be too invasive for the lib itself.
Maybe we can change statsviz's interface for add-on metrics using http package's middleware pattern?

On firefox, all graphs are in-line

Hi,

I tested with Firefox (103.0.2 Arch Linux (64 bits)) and Chromium (104.0.5112.79 Arch Linux (64 bits)). It works perfectly with Chromium but in Firefox, the graphs are not "responsive" and end up in-line.

Left - Firefox
Right - Chromium

image

[bug] beego run statsviz has a javascript error

代码如下:

package handler

import (
	"net/http/pprof"

	"github.com/arl/statsviz"
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
)

func init() {
	// web.Router(defaultPprofPrefix, &PprofController{}, "*:Index")
	web.AutoPrefix(defaultPprofPrefix, &PprofController{})
	// web.Router(defaultStatsvizPrefix, &PprofController{}, "*:StatIndex")
	// web.Router(defaultStatsvizPrefix+":path([\\w]+)", &PprofController{}, "*:StatPath")
	// web.Router(defaultStatsvizPrefix+"ws", &PprofController{}, "*:StatWs")

	web.Any("/debug/pprof/", func(ctx *context.Context) {
		pprof.Index(ctx.ResponseWriter, ctx.Request)
	})

	web.Any(defaultStatsvizPrefix, func(ctx *context.Context) {
		statsviz.Index.ServeHTTP(ctx.ResponseWriter, ctx.Request)
	})

	web.Any(defaultStatsvizPrefix+":path([\\w]+)", func(ctx *context.Context) {
		statsviz.Index.ServeHTTP(ctx.ResponseWriter, ctx.Request)
	})

	web.Any(defaultStatsvizPrefix+"ws", func(ctx *context.Context) {
		statsviz.Ws.ServeHTTP(ctx.ResponseWriter, ctx.Request)
	})
}

错误提示:
image

UI: allow saving plot image as png

Plotly already handles exporting plots as png.

At the moment, the whole plotly bar that normally shows at the top of each plot has been disabled.
We should re-enable it but only keeping the save plot image button.

Example with Chi Router

Chi is is a lightweight router for HTTP services, 100% compatible with net/http. Should be awesome to get an example with it, something like (following the gorilla/mux example):

r := chi.NewRouter()
r.Get("/debug/statsviz/ws", statsviz.Ws)
r.Handle("/debug/statsviz/", statsviz.Index)

[webpage] auto re-connect after restart server?

the main process may be killed and then restarted while developing. but therefore the webpage stopped receiving metrics from the process? so can you please make the webpage reconnect the backend automatically after the restart?

server.freq not used

func SendFrequency(freq time.Duration) OptionFunc {
	return func(s *server) error {
		s.freq = freq
		return nil
	}
}
func sendStats(conn *websocket.Conn) error {
	tick := time.NewTicker(defaultSendFrequency)
	defer tick.Stop()

	var stats stats
	for {
		select {
		case <-tick.C:
			runtime.ReadMemStats(&stats.Mem)
			stats.NumGoroutine = runtime.NumGoroutine()
			if err := conn.WriteJSON(stats); err != nil {
				return err
			}
		}
	}
}

sendStats always use defaultSendFrequency, instead of server.freq.
so that SendFrequency does nothing.

program killed after 1-2 seconds with go 1.21.5

Hi,

When I build a project with go version 1.21.5 the process is killed with signal: killed after 1 or 2 seconds.
I can't catch the signal with signal.Notify, as of yet I have not found any workaround, or fix for this.

It can be reproduced with the basic example.

However when I build the project with go version 1.20.7 everything works as expected.

I'll try to dig more into this when I have time. But someone more familiar with this codebase probably could find the problem faster.

[ui] Improve the scale of the Y axis of sizeClasses heatmap

We're currently using a linear Y axis, which makes low size classes difficulty visible, if not hidden.

linear (default):

image

log 10

Switching to a log 10 axis improves that, but makes the highest size classes barely visible.
image

log 10 axis is obtained by setting the axis type to log in Plotly.

layout: {
    yaxis: {
        title: 'size classes',
        type: 'log', 
    },
},

log 2 ?

Using log 2 could help, but would require manual tick creation (see this plotly issue).

equal heights?

Another possibility is to give each bucket the same height, independently of the actual size class it represents.
Doc

[go] add Custom metrics

Thanks for this tool, it's really useful for debug.

Could it be possible to add custom metrics and not only those expose by runtime?

I'm developping an application and it exposes a lot of internal metrics.

Thank.

[Bug] /debug/statsviz/tippy-bundle.umd.min.js.map 404

/debug/statsviz/libs/js/tippy-bundle.umd.min.js.map 404 Not Found
/debug/statsviz/libs/js/bootstrap-toggle.min.js.map 404 Not Found
/debug/statsviz/libs/js/popper.min.js.map 404 Not Found
/debug/statsviz/libs/js/bootstrap.bundle.min.js.map 404 Not Found

statsviz.TimeSeries.GetValue is called multiple times per second

Open 2 or more pages and you will see the phenomenon

code like this:

statsviz.NewServer(statsviz.TimeseriesPlot(func() statsviz.TimeSeriesPlot {
        plot, _ := statsviz.TimeSeriesPlotConfig{
            Name:  "testCall",
            Title: "testCall",
            Type:  statsviz.Scatter,
            Series: []statsviz.TimeSeries{{
                Name:     "call",
                GetValue: func() float64 {
                    println("call",time.Now().Format(time.DateTime))
                    return float64(0)
                },
            }},
        }.Build()
        return plot
    }()))

Here's the log with 3 pages opened
image

js error

plot.js:215 
        
    Uncaught ReferenceError: tippy is not defined
    at Plot._installHeatmapTooltip (plot.js:215:26)
    at Plot.createElement (plot.js:203:18)
    at attachPlots (app.js:100:14)
    at ws.onmessage (app.js:57:13)

image

Add 'github.com/gorilla/websocket' to 'go.mod' file

First, thank you for the great tool! It really helps to visualize and analyze runtime stats

I noticed that package websocket is a copy of github.com/gorilla/websocket. I would suggest to remove it from the repo and add to go.mod file. Even if there are some changes, it's better to create a fork. What do you say?

Example with Gin

If you are using Gin, I hope the following content can help you:

router = gin.New()
router.GET("/debug/statsviz/*filepath", func(context *gin.Context) {
	if context.Param("filepath") == "/ws" {
		statsviz.Ws(context.Writer, context.Request)
		return
	}
	statsviz.IndexAtRoot("/debug/statsviz").ServeHTTP(context.Writer, context.Request)
})
router.Run(":8080")

Failed example

Fail one: "Not Found."

router = gin.New()
router.GET("/debug/statsviz/ws", gin.WrapF(statsviz.Ws))
router.GET("/debug/statsviz/",  gin.WrapH(statsviz.Index))
router.Run(":8080")

Because /debug/statsviz/ is a static directory, Need to register with router.StaticFS("/more_static", http.Dir("my_file_system"))

gin#serving-static-files

Fail two: "wildcard route conflicts with existing children"

router = gin.New()
router.GET("/debug/statsviz/ws", gin.WrapF(statsviz.Ws))
router.GET("/debug/statsviz/*filepath",  gin.WrapH(statsviz.Index))
router.Run(":8080")

panic: '/ws' in new path '/debug/statsviz/ws' conflicts with existing wildcard '/*filepath' in existing prefix '/debug/statsviz/*filepath'

Related issue:

gin-gonic/gin#2016
gin-gonic/gin#1681

Good debugging tool, hope to help more people.

Dynamic graphs registration

It would be nice to be able to add graphs dynamically. For example, we wanted to convert Prometheus metrics to Statsviz graphs, with one graph per Prometheus label value. But the full set of values is not known in advance, so it is not possible to pass all options to statsviz.Register.

It is almost possible to do now by creating Statsviz HTTP handler on the fly in the other HTTP handler:

// pseudocode
http.HandleFunc("/debug/graphs", func(rw http.ResponseWriter, req *http.Request) {
	s, _ := statsviz.NewServer()
	s.Index().ServeHTTP(rw, req)
})

Unfortunately, there are two handlers: Index() and Ws(). Maybe it is possible to create a single handler that would route to one or another based on, say, HTTP headers?

[feature] allow to hide plots or plot groups

With recent go1.20 and go1.21 metrics, the number of plots is starting to be important.

I think users would benefit from a way to hide and show

    1. single plots (collapse)
    1. multiple categories of plots at once
  1. each plot would be associated to a category tag, and the dashboard would have a new widgets, allowing to select the hide/show plot categories.

  2. on top of each plot there would be a collapse icon (an arrow maybe?) allowing the user to disable a plot.

In addition when a plot is now shown, its plot would not be updated, even though it's circular buffer would continue to get updated, so that when a plot is suddenly activated, its visualized data immediately catches up the plots that remained visible.

[ui] add light/dark mode selector

Add a dark/light mode switch to the top menu.

The thing is to also change the plot background color when in dark mode.

Bonus point: use system setting, if exists

[doc] add issues and pull-request templates

pretty standard stuff, maybe reuse a template or use a template generator?

Issue template should thank the user and ask them:

  • to run go env
  • to share Go code
  • to explain what they did
  • what they were expecting
  • what happened instead

PR template should just thank the user and ask them to link the PR to a specific issue (and possibly to have created that issue first)

Behaviour when stats value is NaN or infinite

We should add unit tests to verify the behaviour if we're trying to encode floating points equals to NaN or infinite, whether they come from runtime/metrics (if that's even possible) or more probably, from user provided values

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.