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 ## Go Ethereum Dashboard
The dashboard is a data visualizer integrated into geth, intended to collect and visualize useful information of an Ethereum node. 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:
Consists of two parts:
* The client visualizes the collected data. * The client visualizes the collected data.
* The server collects the data, and updates the clients. * 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 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].
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`. As the dashboard depends on certain NPM packages (which are not included in the go-ethereum repo), these need to be installed first:
1. `geth --dashboard --vmodule=dashboard=5`.
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`). $ (cd dashboard/assets && npm install)
This way there is no need to stop and regenerate the server to modify the client. ```
### 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` $ (cd dashboard/assets && ./node_modules/.bin/webpack)
1. Enter `localhost:8080` to check the result $ go generate ./dashboard
```
### Have fun ### Have fun

File diff suppressed because one or more lines are too long

View file

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