cmd, dashboard, stateth: requested changes

This commit is contained in:
Kurkó Mihály 2018-06-13 12:14:26 +03:00
parent b99e1a441c
commit ec8a04f5d7
7 changed files with 43 additions and 59 deletions

View file

@ -66,7 +66,6 @@ var (
utils.StatethDashboardsFolderFlag, utils.StatethDashboardsFolderFlag,
utils.StatethGrafanaPortFlag, utils.StatethGrafanaPortFlag,
utils.StatethInfluxdbPortFlag, utils.StatethInfluxdbPortFlag,
utils.StatethRmFlag,
utils.EthashCacheDirFlag, utils.EthashCacheDirFlag,
utils.EthashCachesInMemoryFlag, utils.EthashCachesInMemoryFlag,
utils.EthashCachesOnDiskFlag, utils.EthashCachesOnDiskFlag,

View file

@ -117,7 +117,6 @@ var AppHelpFlagGroups = []flagGroup{
// utils.StatethDashboardsFolderFlag, // utils.StatethDashboardsFolderFlag,
// utils.StatethGrafanaPortFlag, // utils.StatethGrafanaPortFlag,
// utils.StatethInfluxdbPortFlag, // utils.StatethInfluxdbPortFlag,
// utils.StatethRmFlag,
// }, // },
//}, //},
{ {

View file

@ -66,17 +66,13 @@ func main() {
app.Action = func(ctx *cli.Context) error { app.Action = func(ctx *cli.Context) error {
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("loglevel")), log.StreamHandler(os.Stdout, log.TerminalFormat(true)))) log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("loglevel")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
se, err := stateth.New(ctx, &stateth.Config{ se := stateth.New(ctx, &stateth.Config{
DockerPrefix: ctx.String("docker-prefix"), DockerPrefix: ctx.String("docker-prefix"),
GrafanaPort: ctx.Int("grafana-http-port"), GrafanaPort: ctx.Int("grafana-http-port"),
InfluxDBPort: ctx.Int("influxdb-http-port"), InfluxDBPort: ctx.Int("influxdb-http-port"),
DashboardsFolder: ctx.String("grafana-dashboards-folder"), DashboardsFolder: ctx.String("grafana-dashboards-folder"),
Rm: ctx.Bool("rm"),
}) })
if err != nil { if err := se.StartExternal(ctx.Bool("rm")); err != nil {
return err
}
if err = se.StartExternal(); err != nil {
return err return err
} }

View file

@ -230,13 +230,9 @@ var (
} }
StatethInfluxdbPortFlag = cli.IntFlag{ StatethInfluxdbPortFlag = cli.IntFlag{
Name: "stateth.influxdbport", Name: "stateth.influxdbport",
Usage: "Influxdb http port", Usage: "InfluxDB http port",
Value: stateth.DefaultConfig.InfluxDBPort, Value: stateth.DefaultConfig.InfluxDBPort,
} }
StatethRmFlag = cli.BoolFlag{
Name: "stateth.rm",
Usage: "Remove existing stateth network and stateth containers upon startup. Make sure that the start up works every time, even if the service wasn't shut down gracefully.",
}
// Ethash settings // Ethash settings
EthashCacheDirFlag = DirectoryFlag{ EthashCacheDirFlag = DirectoryFlag{
Name: "ethash.cachedir", Name: "ethash.cachedir",
@ -1188,7 +1184,6 @@ func SetStatethConfig(ctx *cli.Context, cfg *stateth.Config) {
cfg.DashboardsFolder = ctx.GlobalString(StatethDashboardsFolderFlag.Name) cfg.DashboardsFolder = ctx.GlobalString(StatethDashboardsFolderFlag.Name)
cfg.GrafanaPort = ctx.GlobalInt(StatethGrafanaPortFlag.Name) cfg.GrafanaPort = ctx.GlobalInt(StatethGrafanaPortFlag.Name)
cfg.InfluxDBPort = ctx.GlobalInt(StatethInfluxdbPortFlag.Name) cfg.InfluxDBPort = ctx.GlobalInt(StatethInfluxdbPortFlag.Name)
cfg.Rm = ctx.GlobalBool(StatethRmFlag.Name)
} }
// RegisterEthService adds an Ethereum client to the stack. // RegisterEthService adds an Ethereum client to the stack.
@ -1223,13 +1218,13 @@ func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit st
var lesServ *les.LightEthereum var lesServ *les.LightEthereum
ctx.Service(&lesServ) ctx.Service(&lesServ)
return dashboard.New(cfg, commit, ethServ, lesServ, ctx.ResolvePath("logs")) return dashboard.New(cfg, commit, ethServ, lesServ, ctx.ResolvePath("logs")), nil
}) })
} }
func RegisterStatethService(stack *node.Node, cfg *stateth.Config, cliCtx *cli.Context) { func RegisterStatethService(stack *node.Node, cfg *stateth.Config, cliCtx *cli.Context) {
stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
return stateth.New(cliCtx, cfg) return stateth.New(cliCtx, cfg), nil
}) })
} }

View file

@ -83,7 +83,7 @@ type client 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, commit string, ethServ *eth.Ethereum, lesServ *les.LightEthereum, logdir string) (*Dashboard, error) { func New(config *Config, commit string, ethServ *eth.Ethereum, lesServ *les.LightEthereum, logdir string) *Dashboard {
now := time.Now() now := time.Now()
versionMeta := "" versionMeta := ""
if len(params.VersionMeta) > 0 { if len(params.VersionMeta) > 0 {
@ -112,7 +112,7 @@ func New(config *Config, commit string, ethServ *eth.Ethereum, lesServ *les.Ligh
ethServ: ethServ, ethServ: ethServ,
lesServ: lesServ, lesServ: lesServ,
logdir: logdir, logdir: logdir,
}, nil }
} }
// emptyChartEntries returns a ChartEntry array containing limit number of empty samples. // emptyChartEntries returns a ChartEntry array containing limit number of empty samples.
@ -263,8 +263,8 @@ func (db *Dashboard) apiHandler(conn *websocket.Conn) {
} }
} }
// metricCollector returns a function, which retrieves a specific metric. // meterCollector returns a function, which retrieves a specific meter.
func metricCollector(name string) func() int64 { func meterCollector(name string) func() int64 {
if metric := metrics.DefaultRegistry.Get(name); metric != nil { if metric := metrics.DefaultRegistry.Get(name); metric != nil {
m := metric.(metrics.Meter) m := metric.(metrics.Meter)
return func() int64 { return func() int64 {
@ -285,10 +285,10 @@ func (db *Dashboard) collectData() {
var ( var (
mem runtime.MemStats mem runtime.MemStats
collectNetworkIngress = metricCollector("p2p/InboundTraffic") collectNetworkIngress = meterCollector("p2p/InboundTraffic")
collectNetworkEgress = metricCollector("p2p/OutboundTraffic") collectNetworkEgress = meterCollector("p2p/OutboundTraffic")
collectDiskRead = metricCollector("eth/db/chaindata/disk/read") collectDiskRead = meterCollector("eth/db/chaindata/disk/read")
collectDiskWrite = metricCollector("eth/db/chaindata/disk/write") collectDiskWrite = meterCollector("eth/db/chaindata/disk/write")
prevNetworkIngress = collectNetworkIngress() prevNetworkIngress = collectNetworkIngress()
prevNetworkEgress = collectNetworkEgress() prevNetworkEgress = collectNetworkEgress()

View file

@ -26,7 +26,6 @@ var DefaultConfig = Config{
DashboardsFolder: os.Getenv("GOPATH") + "/src/github.com/ethereum/go-ethereum/stateth/grafana_dashboards", DashboardsFolder: os.Getenv("GOPATH") + "/src/github.com/ethereum/go-ethereum/stateth/grafana_dashboards",
GrafanaPort: 3000, GrafanaPort: 3000,
InfluxDBPort: 8086, InfluxDBPort: 8086,
Rm: false,
} }
// Config contains the configuration parameters of the dashboard. // Config contains the configuration parameters of the dashboard.
@ -42,8 +41,4 @@ type Config struct {
// InfluxDBPort is the expose port for the InfluxDB HTTP interface. // InfluxDBPort is the expose port for the InfluxDB HTTP interface.
InfluxDBPort int `toml:",omitempty"` InfluxDBPort int `toml:",omitempty"`
// Rm removes existing stateth network and stateth containers upon startup if true.
// Makes sure that the start up works every time, even if the service wasn't shut down gracefully.
Rm bool `toml:",omitempty"`
} }

View file

@ -46,11 +46,11 @@ type Stateth struct {
} }
// New creates a new stateth instance with the given configuration. // New creates a new stateth instance with the given configuration.
func New(ctx *cli.Context, config *Config) (*Stateth, error) { func New(ctx *cli.Context, config *Config) *Stateth {
return &Stateth{ return &Stateth{
ctx: ctx, ctx: ctx,
config: config, config: config,
}, nil }
} }
// Protocols implements the node.Service interface. // Protocols implements the node.Service interface.
@ -62,19 +62,19 @@ func (se *Stateth) APIs() []rpc.API { return nil }
// Start starts InfluxDB and Grafana. // Start starts InfluxDB and Grafana.
// Implements the node.Service interface. // Implements the node.Service interface.
func (se *Stateth) Start(server *p2p.Server) error { func (se *Stateth) Start(server *p2p.Server) error {
return se.StartExternal() return se.StartExternal(true)
} }
// Stop cleans up the containers. // Stop cleans up the containers.
// Implements the node.Service interface. // Implements the node.Service interface.
func (se *Stateth) Stop() error { return se.StopExternal() } func (se *Stateth) Stop() error {
return se.StopExternal()
func (se *Stateth) StartExternal() error {
var err error
if se.config.Rm {
if err = se.cleanupContainers(); err != nil {
return err
} }
func (se *Stateth) StartExternal(rm bool) error {
var err error
if rm {
se.cleanupContainers()
} }
if err = se.runNetwork(); err != nil { if err = se.runNetwork(); err != nil {
return err return err
@ -85,7 +85,7 @@ func (se *Stateth) StartExternal() error {
if err = se.runGrafana(); err != nil { if err = se.runGrafana(); err != nil {
return err return err
} }
log.Info("waiting for grafana to boot up...") log.Info("Waiting for Grafana to boot up...")
time.Sleep(7 * time.Second) // give time to Grafana to boot up time.Sleep(7 * time.Second) // give time to Grafana to boot up
se.gclient, err = gapi.New(fmt.Sprintf("%s:%s", grafanaUser, grafanaPass), fmt.Sprintf("http://localhost:%d", se.config.GrafanaPort)) se.gclient, err = gapi.New(fmt.Sprintf("%s:%s", grafanaUser, grafanaPass), fmt.Sprintf("http://localhost:%d", se.config.GrafanaPort))
@ -99,18 +99,21 @@ func (se *Stateth) StartExternal() error {
if err = se.importGrafanaDashboards(); err != nil { if err = se.importGrafanaDashboards(); err != nil {
return err return err
} }
fmt.Println(fmt.Sprintf("grafana listening on http://localhost:%d", se.config.GrafanaPort)) fmt.Println(fmt.Sprintf("Grafana listening on http://localhost:%d", se.config.GrafanaPort))
fmt.Println(fmt.Sprintf("username: %s", grafanaUser)) fmt.Println(fmt.Sprintf("Username: %s", grafanaUser))
fmt.Println(fmt.Sprintf("password: %s", grafanaPass)) fmt.Println(fmt.Sprintf("Password: %s", grafanaPass))
fmt.Println() fmt.Println()
return nil return nil
} }
func (se *Stateth) StopExternal() error { return se.cleanupContainers() } func (se *Stateth) StopExternal() error {
se.cleanupContainers()
return nil
}
func (se *Stateth) runNetwork() error { func (se *Stateth) runNetwork() error {
log.Info("creating docker network", "network", se.config.DockerPrefix) log.Info("Creating docker network", "network", se.config.DockerPrefix)
command := strings.Split(fmt.Sprintf("docker network create %s", se.config.DockerPrefix), " ") command := strings.Split(fmt.Sprintf("docker network create %s", se.config.DockerPrefix), " ")
r, err := exec.Command(command[0], command[1:]...).CombinedOutput() r, err := exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
@ -121,7 +124,7 @@ func (se *Stateth) runNetwork() error {
} }
func (se *Stateth) runInfluxDB() error { func (se *Stateth) runInfluxDB() error {
log.Info("pulling influxdb:1.5.2 docker image") log.Info("Pulling influxdb:1.5.2 docker image")
command := strings.Split("docker pull influxdb:1.5.2", " ") command := strings.Split("docker pull influxdb:1.5.2", " ")
r, err := exec.Command(command[0], command[1:]...).CombinedOutput() r, err := exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
@ -129,7 +132,7 @@ func (se *Stateth) runInfluxDB() error {
return err return err
} }
log.Info("running influxdb docker container", "container", fmt.Sprintf("%s_influxdb", se.config.DockerPrefix)) log.Info("Running InfluxDB docker container", "container", fmt.Sprintf("%s_influxdb", se.config.DockerPrefix))
command = strings.Split(fmt.Sprintf("docker run --network %s --name %s_influxdb -e INFLUXDB_DB=metrics -e INFLUXDB_ADMIN_USER=%s -e INFLUXDB_ADMIN_PASSWORD=%s -p %d:8086 -d influxdb:1.5.2", se.config.DockerPrefix, se.config.DockerPrefix, influxDBAdminUser, influxDBAdminPass, se.config.InfluxDBPort), " ") command = strings.Split(fmt.Sprintf("docker run --network %s --name %s_influxdb -e INFLUXDB_DB=metrics -e INFLUXDB_ADMIN_USER=%s -e INFLUXDB_ADMIN_PASSWORD=%s -p %d:8086 -d influxdb:1.5.2", se.config.DockerPrefix, se.config.DockerPrefix, influxDBAdminUser, influxDBAdminPass, se.config.InfluxDBPort), " ")
r, err = exec.Command(command[0], command[1:]...).CombinedOutput() r, err = exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
@ -140,7 +143,7 @@ func (se *Stateth) runInfluxDB() error {
} }
func (se *Stateth) runGrafana() error { func (se *Stateth) runGrafana() error {
log.Info("pulling grafana/grafana:5.1.3 docker image") log.Info("Pulling grafana/grafana:5.1.3 docker image")
command := strings.Split("docker pull grafana/grafana:5.1.3", " ") command := strings.Split("docker pull grafana/grafana:5.1.3", " ")
r, err := exec.Command(command[0], command[1:]...).CombinedOutput() r, err := exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
@ -148,8 +151,7 @@ func (se *Stateth) runGrafana() error {
return err return err
} }
log.Info("running grafana docker container", "container", fmt.Sprintf("%s_grafana", se.config.DockerPrefix)) log.Info("Running Grafana docker container", "container", fmt.Sprintf("%s_grafana", se.config.DockerPrefix))
//command = strings.Split(fmt.Sprintf("docker run --network %s --name=%s_grafana -p %d:3000 -d grafana/grafana:5.1.3", se.config.DockerPrefix, se.config.DockerPrefix, se.config.GrafanaPort), " ")
command = strings.Split(fmt.Sprintf("docker run --network %s --name=%s_grafana -e GF_AUTH_ANONYMOUS_ENABLED=true -p %d:3000 -d grafana/grafana:5.1.3", se.config.DockerPrefix, se.config.DockerPrefix, se.config.GrafanaPort), " ") command = strings.Split(fmt.Sprintf("docker run --network %s --name=%s_grafana -e GF_AUTH_ANONYMOUS_ENABLED=true -p %d:3000 -d grafana/grafana:5.1.3", se.config.DockerPrefix, se.config.DockerPrefix, se.config.GrafanaPort), " ")
r, err = exec.Command(command[0], command[1:]...).CombinedOutput() r, err = exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
@ -159,33 +161,31 @@ func (se *Stateth) runGrafana() error {
return nil return nil
} }
func (se *Stateth) cleanupContainers() error { func (se *Stateth) cleanupContainers() {
log.Info("removing influxdb container") log.Info("Removing InfluxDB container")
command := strings.Split(fmt.Sprintf("docker rm -f %s_influxdb", se.config.DockerPrefix), " ") command := strings.Split(fmt.Sprintf("docker rm -f %s_influxdb", se.config.DockerPrefix), " ")
r, err := exec.Command(command[0], command[1:]...).CombinedOutput() r, err := exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
log.Warn(string(r)) log.Warn(string(r))
} }
log.Info("removing grafana container") log.Info("Removing Grafana container")
command = strings.Split(fmt.Sprintf("docker rm -f %s_grafana", se.config.DockerPrefix), " ") command = strings.Split(fmt.Sprintf("docker rm -f %s_grafana", se.config.DockerPrefix), " ")
r, err = exec.Command(command[0], command[1:]...).CombinedOutput() r, err = exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
log.Warn(string(r)) log.Warn(string(r))
} }
log.Info("removing network") log.Info("Removing network")
command = strings.Split(fmt.Sprintf("docker network rm %s", se.config.DockerPrefix), " ") command = strings.Split(fmt.Sprintf("docker network rm %s", se.config.DockerPrefix), " ")
r, err = exec.Command(command[0], command[1:]...).CombinedOutput() r, err = exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil { if err != nil {
log.Warn(string(r)) log.Warn(string(r))
} }
return nil
} }
func (se *Stateth) importGrafanaDatasource() error { func (se *Stateth) importGrafanaDatasource() error {
log.Info("importing grafana datasource") log.Info("Importing Grafana datasource")
dataSource := &gapi.DataSource{ dataSource := &gapi.DataSource{
Name: "metrics", Name: "metrics",
@ -209,7 +209,7 @@ func (se *Stateth) importGrafanaDatasource() error {
} }
func (se *Stateth) importGrafanaDashboards() error { func (se *Stateth) importGrafanaDashboards() error {
log.Info("importing grafana dashboards") log.Info("Importing Grafana dashboards")
files, err := ioutil.ReadDir(se.config.DashboardsFolder) files, err := ioutil.ReadDir(se.config.DashboardsFolder)
if err != nil { if err != nil {
@ -220,7 +220,7 @@ func (se *Stateth) importGrafanaDashboards() error {
for _, f := range files { for _, f := range files {
name := f.Name() name := f.Name()
if strings.Contains(name, "json") { if strings.Contains(name, "json") {
log.Info("importing dashboard", "dashboard", name) log.Info("Importing dashboard", "dashboard", name)
blob, err := ioutil.ReadFile(filepath.Join(se.config.DashboardsFolder, name)) blob, err := ioutil.ReadFile(filepath.Join(se.config.DashboardsFolder, name))
if err != nil { if err != nil {
@ -245,7 +245,7 @@ func (se *Stateth) prepareDashboardModel(configJSON string) map[string]interface
configMap := map[string]interface{}{} configMap := map[string]interface{}{}
err := json.Unmarshal([]byte(configJSON), &configMap) err := json.Unmarshal([]byte(configJSON), &configMap)
if err != nil { if err != nil {
panic("invalid JSON got into prepare func") panic("Invalid JSON got into prepare func")
} }
delete(configMap, "id") delete(configMap, "id")