2017-11-14 17:34:00 +00:00
|
|
|
// Copyright 2017 The go-ethereum Authors
|
|
|
|
// This file is part of the go-ethereum library.
|
|
|
|
//
|
|
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
package dashboard
|
|
|
|
|
2018-03-08 08:22:21 +00:00
|
|
|
//go:generate yarn --cwd ./assets install
|
|
|
|
//go:generate yarn --cwd ./assets build
|
2019-03-13 12:53:52 +00:00
|
|
|
//go:generate yarn --cwd ./assets js-beautify -f bundle.js.map -r -w 1
|
|
|
|
//go:generate go-bindata -nometadata -o assets.go -prefix assets -nocompress -pkg dashboard assets/index.html assets/bundle.js assets/bundle.js.map
|
2018-01-15 09:20:00 +00:00
|
|
|
//go:generate sh -c "sed 's#var _bundleJs#//nolint:misspell\\\n&#' assets.go > assets.go.tmp && mv assets.go.tmp assets.go"
|
2019-03-13 12:53:52 +00:00
|
|
|
//go:generate sh -c "sed 's#var _bundleJsMap#//nolint:misspell\\\n&#' assets.go > assets.go.tmp && mv assets.go.tmp assets.go"
|
2018-03-08 08:22:21 +00:00
|
|
|
//go:generate sh -c "sed 's#var _indexHtml#//nolint:misspell\\\n&#' assets.go > assets.go.tmp && mv assets.go.tmp assets.go"
|
2018-01-08 12:15:57 +00:00
|
|
|
//go:generate gofmt -w -s assets.go
|
2017-11-14 17:34:00 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
"io"
|
2017-11-14 17:34:00 +00:00
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/eth"
|
|
|
|
"github.com/ethereum/go-ethereum/event"
|
|
|
|
"github.com/ethereum/go-ethereum/les"
|
2017-11-14 17:34:00 +00:00
|
|
|
"github.com/ethereum/go-ethereum/log"
|
|
|
|
"github.com/ethereum/go-ethereum/p2p"
|
2018-01-15 09:20:00 +00:00
|
|
|
"github.com/ethereum/go-ethereum/params"
|
2017-11-14 17:34:00 +00:00
|
|
|
"github.com/ethereum/go-ethereum/rpc"
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
"github.com/mohae/deepcopy"
|
2017-11-14 17:34:00 +00:00
|
|
|
"golang.org/x/net/websocket"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
sampleLimit = 200 // Maximum number of data samples
|
|
|
|
dataCollectorCount = 4
|
2017-11-14 17:34:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Dashboard contains the dashboard internals.
|
|
|
|
type Dashboard struct {
|
2019-03-13 12:53:52 +00:00
|
|
|
config *Config // Configuration values for the dashboard
|
|
|
|
|
|
|
|
listener net.Listener // Network listener listening for dashboard clients
|
|
|
|
conns map[uint32]*client // Currently live websocket connections
|
|
|
|
nextConnID uint32 // Next connection id
|
|
|
|
|
|
|
|
history *Message // Stored historical data
|
2017-11-14 17:34:00 +00:00
|
|
|
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
lock sync.Mutex // Lock protecting the dashboard's internals
|
|
|
|
chainLock sync.RWMutex // Lock protecting the stored blockchain data
|
|
|
|
sysLock sync.RWMutex // Lock protecting the stored system data
|
|
|
|
peerLock sync.RWMutex // Lock protecting the stored peer data
|
|
|
|
logLock sync.RWMutex // Lock protecting the stored log data
|
2017-11-14 17:34:00 +00:00
|
|
|
|
2019-03-13 12:53:52 +00:00
|
|
|
geodb *geoDB // geoip database instance for IP to geographical information conversions
|
|
|
|
logdir string // Directory containing the log files
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
|
2017-11-14 17:34:00 +00:00
|
|
|
quit chan chan error // Channel used for graceful exit
|
2019-03-13 12:53:52 +00:00
|
|
|
wg sync.WaitGroup // Wait group used to close the data collector threads
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
|
|
|
|
peerCh chan p2p.MeteredPeerEvent // Peer event channel.
|
|
|
|
subPeer event.Subscription // Peer event subscription.
|
|
|
|
|
|
|
|
ethServ *eth.Ethereum // Ethereum object serving internals.
|
|
|
|
lesServ *les.LightEthereum // LightEthereum object serving internals.
|
2017-11-14 17:34:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// client represents active websocket connection with a remote browser.
|
|
|
|
type client struct {
|
|
|
|
conn *websocket.Conn // Particular live websocket connection
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
msg chan *Message // Message queue for the update messages
|
2017-11-14 17:34:00 +00:00
|
|
|
logger log.Logger // Logger for the particular live websocket connection
|
|
|
|
}
|
|
|
|
|
|
|
|
// New creates a new dashboard instance with the given configuration.
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
func New(config *Config, ethServ *eth.Ethereum, lesServ *les.LightEthereum, commit string, logdir string) *Dashboard {
|
|
|
|
// There is a data race between the network layer and the dashboard, which
|
|
|
|
// can cause some lost peer events, therefore some peers might not appear
|
|
|
|
// on the dashboard.
|
|
|
|
// In order to solve this problem, the peer event subscription is registered
|
|
|
|
// here, before the network layer starts.
|
|
|
|
peerCh := make(chan p2p.MeteredPeerEvent, p2p.MeteredPeerLimit)
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
versionMeta := ""
|
|
|
|
if len(params.VersionMeta) > 0 {
|
|
|
|
versionMeta = fmt.Sprintf(" (%s)", params.VersionMeta)
|
|
|
|
}
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
var genesis common.Hash
|
|
|
|
if ethServ != nil {
|
|
|
|
genesis = ethServ.BlockChain().Genesis().Hash()
|
|
|
|
} else if lesServ != nil {
|
|
|
|
genesis = lesServ.BlockChain().Genesis().Hash()
|
|
|
|
}
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
return &Dashboard{
|
2017-11-14 17:34:00 +00:00
|
|
|
conns: make(map[uint32]*client),
|
|
|
|
config: config,
|
|
|
|
quit: make(chan chan error),
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
history: &Message{
|
|
|
|
General: &GeneralMessage{
|
|
|
|
Commit: commit,
|
|
|
|
Version: fmt.Sprintf("v%d.%d.%d%s", params.VersionMajor, params.VersionMinor, params.VersionPatch, versionMeta),
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
Genesis: genesis,
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
},
|
|
|
|
System: &SystemMessage{
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
ActiveMemory: emptyChartEntries(sampleLimit),
|
|
|
|
VirtualMemory: emptyChartEntries(sampleLimit),
|
|
|
|
NetworkIngress: emptyChartEntries(sampleLimit),
|
|
|
|
NetworkEgress: emptyChartEntries(sampleLimit),
|
|
|
|
ProcessCPU: emptyChartEntries(sampleLimit),
|
|
|
|
SystemCPU: emptyChartEntries(sampleLimit),
|
|
|
|
DiskRead: emptyChartEntries(sampleLimit),
|
|
|
|
DiskWrite: emptyChartEntries(sampleLimit),
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
},
|
2017-12-21 15:54:38 +00:00
|
|
|
},
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
logdir: logdir,
|
|
|
|
peerCh: peerCh,
|
|
|
|
subPeer: p2p.SubscribeMeteredPeerEvent(peerCh),
|
|
|
|
ethServ: ethServ,
|
|
|
|
lesServ: lesServ,
|
2018-01-23 20:51:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// emptyChartEntries returns a ChartEntry array containing limit number of empty samples.
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
func emptyChartEntries(limit int) ChartEntries {
|
2018-01-23 20:51:04 +00:00
|
|
|
ce := make(ChartEntries, limit)
|
|
|
|
for i := 0; i < limit; i++ {
|
2019-03-13 12:53:52 +00:00
|
|
|
ce[i] = new(ChartEntry)
|
2018-01-23 20:51:04 +00:00
|
|
|
}
|
|
|
|
return ce
|
2017-11-14 17:34:00 +00:00
|
|
|
}
|
|
|
|
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
// Protocols implements the node.Service interface.
|
2017-11-14 17:34:00 +00:00
|
|
|
func (db *Dashboard) Protocols() []p2p.Protocol { return nil }
|
|
|
|
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
// APIs implements the node.Service interface.
|
2017-11-14 17:34:00 +00:00
|
|
|
func (db *Dashboard) APIs() []rpc.API { return nil }
|
|
|
|
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
// Start starts the data collection thread and the listening server of the dashboard.
|
|
|
|
// Implements the node.Service interface.
|
2017-11-14 17:34:00 +00:00
|
|
|
func (db *Dashboard) Start(server *p2p.Server) error {
|
2019-09-24 08:08:46 +00:00
|
|
|
log.Info("Starting dashboard", "url", fmt.Sprintf("http://%s:%d", db.config.Host, db.config.Port))
|
2018-01-15 09:20:00 +00:00
|
|
|
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
db.wg.Add(dataCollectorCount)
|
|
|
|
go db.collectChainData()
|
2019-03-13 12:53:52 +00:00
|
|
|
go db.collectSystemData()
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
go db.streamLogs()
|
2019-03-13 12:53:52 +00:00
|
|
|
go db.collectPeerData()
|
2017-11-14 17:34:00 +00:00
|
|
|
|
|
|
|
http.HandleFunc("/", db.webHandler)
|
|
|
|
http.Handle("/api", websocket.Handler(db.apiHandler))
|
|
|
|
|
|
|
|
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", db.config.Host, db.config.Port))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
db.listener = listener
|
|
|
|
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
go func() {
|
|
|
|
if err := http.Serve(listener, nil); err != http.ErrServerClosed {
|
|
|
|
log.Warn("Could not accept incoming HTTP connections", "err", err)
|
|
|
|
}
|
|
|
|
}()
|
2017-11-14 17:34:00 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
// Stop stops the data collection thread and the connection listener of the dashboard.
|
|
|
|
// Implements the node.Service interface.
|
2017-11-14 17:34:00 +00:00
|
|
|
func (db *Dashboard) Stop() error {
|
|
|
|
// Close the connection listener.
|
|
|
|
var errs []error
|
|
|
|
if err := db.listener.Close(); err != nil {
|
|
|
|
errs = append(errs, err)
|
|
|
|
}
|
|
|
|
// Close the collectors.
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
errc := make(chan error, dataCollectorCount)
|
|
|
|
for i := 0; i < dataCollectorCount; i++ {
|
2017-11-14 17:34:00 +00:00
|
|
|
db.quit <- errc
|
|
|
|
if err := <-errc; err != nil {
|
|
|
|
errs = append(errs, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Close the connections.
|
|
|
|
db.lock.Lock()
|
|
|
|
for _, c := range db.conns {
|
|
|
|
if err := c.conn.Close(); err != nil {
|
|
|
|
c.logger.Warn("Failed to close connection", "err", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
db.lock.Unlock()
|
|
|
|
|
|
|
|
// Wait until every goroutine terminates.
|
|
|
|
db.wg.Wait()
|
|
|
|
log.Info("Dashboard stopped")
|
|
|
|
|
|
|
|
var err error
|
|
|
|
if len(errs) > 0 {
|
|
|
|
err = fmt.Errorf("%v", errs)
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// webHandler handles all non-api requests, simply flattening and returning the dashboard website.
|
|
|
|
func (db *Dashboard) webHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
log.Debug("Request", "URL", r.URL)
|
|
|
|
|
|
|
|
path := r.URL.String()
|
|
|
|
if path == "/" {
|
2018-03-08 08:22:21 +00:00
|
|
|
path = "/index.html"
|
2017-11-14 17:34:00 +00:00
|
|
|
}
|
2018-01-15 09:20:00 +00:00
|
|
|
blob, err := Asset(path[1:])
|
2017-11-14 17:34:00 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Warn("Failed to load the asset", "path", path, "err", err)
|
|
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
w.Write(blob)
|
|
|
|
}
|
|
|
|
|
|
|
|
// apiHandler handles requests for the dashboard.
|
|
|
|
func (db *Dashboard) apiHandler(conn *websocket.Conn) {
|
2019-03-13 12:53:52 +00:00
|
|
|
id := atomic.AddUint32(&db.nextConnID, 1)
|
2017-11-14 17:34:00 +00:00
|
|
|
client := &client{
|
|
|
|
conn: conn,
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
msg: make(chan *Message, 128),
|
2017-11-14 17:34:00 +00:00
|
|
|
logger: log.New("id", id),
|
|
|
|
}
|
2017-12-21 15:54:38 +00:00
|
|
|
done := make(chan struct{})
|
2017-11-14 17:34:00 +00:00
|
|
|
|
|
|
|
// Start listening for messages to send.
|
|
|
|
db.wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer db.wg.Done()
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-done:
|
|
|
|
return
|
|
|
|
case msg := <-client.msg:
|
|
|
|
if err := websocket.JSON.Send(client.conn, msg); err != nil {
|
|
|
|
client.logger.Warn("Failed to send the message", "msg", msg, "err", err)
|
|
|
|
client.conn.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
2018-01-15 09:20:00 +00:00
|
|
|
|
2017-11-14 17:34:00 +00:00
|
|
|
// Send the past data.
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
db.chainLock.RLock()
|
2019-03-13 12:53:52 +00:00
|
|
|
db.sysLock.RLock()
|
|
|
|
db.peerLock.RLock()
|
|
|
|
db.logLock.RLock()
|
|
|
|
|
|
|
|
h := deepcopy.Copy(db.history).(*Message)
|
|
|
|
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
db.chainLock.RUnlock()
|
2019-03-13 12:53:52 +00:00
|
|
|
db.sysLock.RUnlock()
|
|
|
|
db.peerLock.RUnlock()
|
|
|
|
db.logLock.RUnlock()
|
|
|
|
|
2017-11-14 17:34:00 +00:00
|
|
|
// Start tracking the connection and drop at connection loss.
|
2019-03-13 12:53:52 +00:00
|
|
|
db.lock.Lock()
|
dashboard: send current block to the dashboard client (#19762)
This adds all dashboard changes from the last couple months.
We're about to remove the dashboard, but decided that we should
get all the recent work in first in case anyone wants to pick up this
project later on.
* cmd, dashboard, eth, p2p: send peer info to the dashboard
* dashboard: update npm packages, improve UI, rebase
* dashboard, p2p: remove println, change doc
* cmd, dashboard, eth, p2p: cleanup after review
* dashboard: send current block to the dashboard client
2019-11-13 11:13:13 +00:00
|
|
|
client.msg <- h
|
2017-11-14 17:34:00 +00:00
|
|
|
db.conns[id] = client
|
|
|
|
db.lock.Unlock()
|
|
|
|
defer func() {
|
|
|
|
db.lock.Lock()
|
|
|
|
delete(db.conns, id)
|
|
|
|
db.lock.Unlock()
|
|
|
|
}()
|
|
|
|
for {
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
r := new(Request)
|
|
|
|
if err := websocket.JSON.Receive(conn, r); err != nil {
|
|
|
|
if err != io.EOF {
|
|
|
|
client.logger.Warn("Failed to receive request", "err", err)
|
|
|
|
}
|
2017-11-14 17:34:00 +00:00
|
|
|
close(done)
|
|
|
|
return
|
|
|
|
}
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
if r.Logs != nil {
|
|
|
|
db.handleLogRequest(r.Logs, client)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-14 17:34:00 +00:00
|
|
|
// sendToAll sends the given message to the active dashboards.
|
2017-12-21 15:54:38 +00:00
|
|
|
func (db *Dashboard) sendToAll(msg *Message) {
|
2017-11-14 17:34:00 +00:00
|
|
|
db.lock.Lock()
|
|
|
|
for _, c := range db.conns {
|
|
|
|
select {
|
cmd, dashboard, log: log collection and exploration (#17097)
* cmd, dashboard, internal, log, node: logging feature
* cmd, dashboard, internal, log: requested changes
* dashboard, vendor: gofmt, govendor, use vendored file watcher
* dashboard, log: gofmt -s -w, goimports
* dashboard, log: gosimple
2018-07-11 07:59:04 +00:00
|
|
|
case c.msg <- msg:
|
2017-11-14 17:34:00 +00:00
|
|
|
default:
|
|
|
|
c.conn.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
db.lock.Unlock()
|
|
|
|
}
|