dashboard: minor text and code polishes

This commit is contained in:
Péter Szilágyi 2017-11-14 18:56:15 +02:00
parent 5c4c879b1a
commit a77f486aaf
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D
3 changed files with 40 additions and 41 deletions

View file

@ -1,35 +1,33 @@
## Go Ethereum Dashboard
The dashboard is a data visualizer integrated into geth, intended to collect and visualize useful information of an Ethereum node.
Consists of two parts:
The dashboard is a data visualizer integrated into geth, intended to collect and visualize useful information of an Ethereum node. It consists of two parts:
* The client visualizes the collected data.
* The server collects the data, and updates the clients.
The client's UI uses [React][React] with JSX syntax, which is validated by the [ESLint][ESLint] linter
mostly according to the [Airbnb React/JSX Style Guide][Airbnb]. The style is defined in the `.eslintrc` configuration file.
The resources are bundled into a single `bundle.js` file using [Webpack][Webpack], which relies on the `webpack.config.js`.
The bundled file is referenced from `dashboard.html` and takes part in the `assets.go` too.
The necessary dependencies for the module bundler are gathered by [Node.js][Node.js].
The client's UI uses [React][React] with JSX syntax, which is validated by the [ESLint][ESLint] linter mostly according to the [Airbnb React/JSX Style Guide][Airbnb]. The style is defined in the `.eslintrc` configuration file. The resources are bundled into a single `bundle.js` file using [Webpack][Webpack], which relies on the `webpack.config.js`. The bundled file is referenced from `dashboard.html` and takes part in the `assets.go` too. The necessary dependencies for the module bundler are gathered by [Node.js][Node.js].
### Install and run the server
### Development and bundling
1. `go generate ./dashboard && go install -v ./cmd/geth`.
1. `geth --dashboard --vmodule=dashboard=5`.
As the dashboard depends on certain NPM packages (which are not included in the go-ethereum repo), these need to be installed first:
During the development use the `--dashboard.assets=<absolute path>` flag to set the assets' path
(e.g. `geth --rinkeby --dashboard --dashboard.assets="<path>/dashboard/assets/public" --vmodule=dashboard=5 console`).
This way there is no need to stop and regenerate the server to modify the client.
```
$ (cd dashboard/assets && npm install)
```
### Install the module bundler
Normally the dashboard assets are bundled into Geth via `go-bindata` to avoid external dependencies. Rebuilding Geth after each UI modification however is not feasible from a developer perspective. Instead, we can run `webpack` in watch mode to automatically rebundle the UI, and ask `geth` to use external assets to not rely on compiled resources:
1. `cd dashboard/assets`
1. `npm install`
```
$ (cd dashboard/assets && ./node_modules/.bin/webpack --watch)
$ geth --dashboard --dashboard.assets=dashboard/assets/public --vmodule=dashboard=5
```
### Bundle the resources
To bundle up the final UI into Geth, run `webpack` and `go generate`:
1. `cd dashboard/assets`
1. `./node_modules/.bin/webpack`
1. Enter `localhost:8080` to check the result
```
$ (cd dashboard/assets && ./node_modules/.bin/webpack)
$ go generate ./dashboard
```
### Have fun

File diff suppressed because one or more lines are too long

View file

@ -20,11 +20,6 @@ package dashboard
import (
"fmt"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
"github.com/rcrowley/go-metrics"
"golang.org/x/net/websocket"
"io/ioutil"
"net"
"net/http"
@ -32,6 +27,12 @@ import (
"sync"
"sync/atomic"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
"github.com/rcrowley/go-metrics"
"golang.org/x/net/websocket"
)
const (
@ -41,8 +42,8 @@ const (
var nextId uint32 // Next connection id
// dashboard contains the dashboard internals.
type dashboard struct {
// Dashboard contains the dashboard internals.
type Dashboard struct {
config *Config
listener net.Listener
@ -82,8 +83,8 @@ type chartEntry struct {
}
// New creates a new dashboard instance with the given configuration.
func New(config *Config) (*dashboard, error) {
return &dashboard{
func New(config *Config) (*Dashboard, error) {
return &Dashboard{
conns: make(map[uint32]*client),
config: config,
quit: make(chan chan error),
@ -91,13 +92,13 @@ func New(config *Config) (*dashboard, error) {
}
// Protocols is a meaningless implementation of node.Service.
func (db *dashboard) Protocols() []p2p.Protocol { return nil }
func (db *Dashboard) Protocols() []p2p.Protocol { return nil }
// APIs is a meaningless implementation of node.Service.
func (db *dashboard) APIs() []rpc.API { return nil }
func (db *Dashboard) APIs() []rpc.API { return nil }
// Start implements node.Service, starting the data collection thread and the listening server of the dashboard.
func (db *dashboard) Start(server *p2p.Server) error {
func (db *Dashboard) Start(server *p2p.Server) error {
db.wg.Add(2)
go db.collectData()
go db.collectLogs() // In case of removing this line change 2 back to 1 in wg.Add.
@ -117,7 +118,7 @@ func (db *dashboard) Start(server *p2p.Server) error {
}
// Stop implements node.Service, stopping the data collection thread and the connection listener of the dashboard.
func (db *dashboard) Stop() error {
func (db *Dashboard) Stop() error {
// Close the connection listener.
var errs []error
if err := db.listener.Close(); err != nil {
@ -153,8 +154,8 @@ func (db *dashboard) Stop() error {
}
// webHandler handles all non-api requests, simply flattening and returning the dashboard website.
func (db *dashboard) webHandler(w http.ResponseWriter, r *http.Request) {
log.Info("Request", "URL", r.URL)
func (db *Dashboard) webHandler(w http.ResponseWriter, r *http.Request) {
log.Debug("Request", "URL", r.URL)
path := r.URL.String()
if path == "/" {
@ -181,7 +182,7 @@ func (db *dashboard) webHandler(w http.ResponseWriter, r *http.Request) {
}
// apiHandler handles requests for the dashboard.
func (db *dashboard) apiHandler(conn *websocket.Conn) {
func (db *Dashboard) apiHandler(conn *websocket.Conn) {
id := atomic.AddUint32(&nextId, 1)
client := &client{
conn: conn,
@ -232,7 +233,7 @@ func (db *dashboard) apiHandler(conn *websocket.Conn) {
}
// collectData collects the required data to plot on the dashboard.
func (db *dashboard) collectData() {
func (db *Dashboard) collectData() {
defer db.wg.Done()
for {
@ -273,7 +274,7 @@ func (db *dashboard) collectData() {
}
// collectLogs collects and sends the logs to the active dashboards.
func (db *dashboard) collectLogs() {
func (db *Dashboard) collectLogs() {
defer db.wg.Done()
// TODO (kurkomisi): log collection comes here.
@ -291,7 +292,7 @@ func (db *dashboard) collectLogs() {
}
// sendToAll sends the given message to the active dashboards.
func (db *dashboard) sendToAll(msg *message) {
func (db *Dashboard) sendToAll(msg *message) {
db.lock.Lock()
for _, c := range db.conns {
select {