Skip to content
PinableAgentsPublic
forked from arl/statsviz

About

Visualise Go runtime metrics in real time

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Statsviz

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

This fork is maintained by PinableAgents and is based on arl/statsviz. The logo and documentation screenshots below are hosted by the upstream project.

statsviz ui statsviz ui

Install

Get the latest version:

go get github.com/PinableAgents/statsviz@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

SQLite History

History is opt-in. Programs that do not import history/sqlite do not link the SQLite driver. To retain metrics across browser refreshes and normal process restarts, open a dedicated database file and pass the store to History:

store, err := sqlitehistory.Open("/var/lib/myapp/statsviz.db", sqlitehistory.Options{
    Retention: 7 * 24 * time.Hour,
})
if err != nil { /* handle error */ }

srv, err := statsviz.NewServer(statsviz.History(store))
if err != nil {
    _ = store.Close()
    /* handle error */
}

appMux := http.NewServeMux()
// Register on the application's existing mux.
srv.Register(appMux)

// 关闭时先停止采集并刷新队列。Store 由调用方持有,必须等
// Server.Close 返回后再关闭。
if err := srv.Close(); err != nil { /* handle flush error */ }
if err := store.Close(); err != nil { /* handle close error */ }

For a diagnostics listener on its own configurable port, use a dedicated mux and HTTP server. Keeping this listener on loopback also avoids exposing runtime metrics on the public application listener:

statsMux := http.NewServeMux()
srv.Register(statsMux)

statsAddr := os.Getenv("STATSVIZ_ADDR")
if statsAddr == "" {
    statsAddr = "127.0.0.1:8095"
}
statsHTTP := &http.Server{
    Addr:    statsAddr,
    Handler: statsMux,
}
go func() {
    if err := statsHTTP.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
        log.Printf("statsviz HTTP server: %v", err)
    }
}()

Import the adapter as sqlitehistory "github.com/PinableAgents/statsviz/history/sqlite". The default retention window is seven days; the query layer clips results to retained data. The database path is chosen by the application, and its parent directory is created when needed. See _example/history for a complete server with configurable address and database path.

With history enabled, use “查看历史” in the top bar to open the history controls: 1h, 6h, 24h and 7d presets, custom start/end times, a timeline slider, and actual sample details. Historical views stay fixed while collection continues; use “返回实时” to collapse the controls and restore the previous live time range. Zooming or panning a plot, or inspecting a sample, also opens the history controls. Long ranges use persisted rollups and adapt their resolution to the response budget, while point queries read the original snapshots. See the SQLite history design for storage limits, aggregation semantics and validation results. The opt-in capacity validation tool builds a full seven-day fixture and records storage and query measurements.

The registered HTTP endpoints follow the configured Root (the default paths are shown below). All timestamps are UTC Unix milliseconds and range intervals are left-closed, right-open:

  • GET /debug/statsviz/history/meta
  • GET /debug/statsviz/history/range?from=...&to=...&run_id=...&max_points=1500&plots=...
  • GET /debug/statsviz/history/point?at=...&run_id=...&tolerance_ms=...

One database file supports one collecting process at a time. Samples already committed survive normal restarts, while samples still in the in-memory queue can be lost after a crash or forced termination. SQLite normally reuses freed pages, so the database file may remain near its historical high-water size even after old samples expire. Retention is bounded by available disk space; it is not an unconditional storage guarantee.

Examples

If you check any of the boxes below:

  • you use some HTTP framework
  • you want Statsviz to be located at /my/path/to/statsviz rather than /debug/statsviz
  • you want Statsviz under https:// rather than http://
  • you want Statsviz behind some middleware

Then you should call statsviz.NewServer() (with or without options depending on your use case) in order to access the Index() and Ws() methods.

srv, err := statsviz.NewServer(); // Create server or handle error
if err != nil { /* handle error */ }

// Do something with the handlers.
srv.Index()     // UI (dashboard) handler func
srv.Ws()        // Websocket handler func

Examples for the following cases, and more, are found in the _example directory:

  • 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:

How Does That Work?

Statsviz is made of two parts:

  • The Ws serves a Websocket endpoint. When a client connects, your program's runtime/metrics are sent to the browser, once per second, via the websocket connection.

  • the Index http handler serves Statsviz user interface at /debug/statsviz at the address served by your program. When served, the UI connects to the Websocket endpoint and starts receiving data points.

Documentation

Go API

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

Web User Interface

Use the language selector in the top toolbar to switch between English and Simplified Chinese. The initial language follows your browser preferences; your selection is saved locally. Controls, chart tooltips, plot descriptions, and history details follow the selected language. Go API names and metric paths retain their original spelling.

Click a chart or query an actual sample to view its details in a scrollable dialog. Close it with the close button, Escape, or a click outside the dialog.

Top Bar

webui-annotated

Category Selector

menu-categories

Each plot belongs to one or more categories. The category selector allows you to filter the visible plots by categories.

Visible Time Range

menu-timerange

Use the time range selector to define the visualized time span.

Show/Hide GC events

menu-gc-events

Show or hide the vertical lines representing garbage collection events.

Pause updates

menu-play

Pause or resume the plot updates.

Plot Controls

webui-annotated

Plots

Which plots are visible depends on:

  • your Go version,since some plots are only available in newer versions.
  • what plot categories are currently selected. By default all plots are shown.

Allocation and Free Rate

alloc-free-rate

CGO Calls

cgo

CPU (GC)

cpu-gc

CPU (Overall)

cpu-overall

CPU (Scavenger)

cpu-scavenger

Garbage Collection

garbage-collection

GC Cycles

gc-cycles

GC Pauses

gc-pauses

GC Scan

gc-scan

GC Stack Size

gc-stack-size

Goroutines

goroutines

Heap (Details)

heap-details

Live Bytes

live-bytes

Live Objects

live-objects

Memory Classes

memory-classes

MSpan/MCache

mspan-mcache

Mutex Wait

mutex-wait

Runnable Time

runnable-time

Scheduling Events

sched-events

Size Classes

size-classes

GC Pauses

gc-pauses

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.

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

About

Visualise Go runtime metrics in real time

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages