github.com/waltonchain/waltonchain_gwtc_src@v1.1.4-0.20201225072101-8a298c95a819/cmd/puppeth/wizard_netstats.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of go-wtc. 3 // 4 // go-wtc is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-wtc is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-wtc. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "os" 23 "strings" 24 25 "github.com/wtc/go-wtc/core" 26 "github.com/wtc/go-wtc/log" 27 "github.com/olekukonko/tablewriter" 28 ) 29 30 // networkStats verifies the status of network components and generates a protip 31 // configuration set to give users hints on how to do various tasks. 32 func (w *wizard) networkStats(tips bool) { 33 if len(w.servers) == 0 { 34 log.Error("No remote machines to gather stats from") 35 return 36 } 37 protips := new(protips) 38 39 // Iterate over all the specified hosts and check their status 40 stats := tablewriter.NewWriter(os.Stdout) 41 stats.SetHeader([]string{"Server", "IP", "Status", "Service", "Details"}) 42 stats.SetColWidth(100) 43 44 for server, pubkey := range w.conf.Servers { 45 client := w.servers[server] 46 logger := log.New("server", server) 47 logger.Info("Starting remote server health-check") 48 49 // If the server is not connected, try to connect again 50 if client == nil { 51 conn, err := dial(server, pubkey) 52 if err != nil { 53 logger.Error("Failed to establish remote connection", "err", err) 54 stats.Append([]string{server, "", err.Error(), "", ""}) 55 continue 56 } 57 client = conn 58 } 59 // Client connected one way or another, run health-checks 60 services := make(map[string]string) 61 logger.Debug("Checking for nginx availability") 62 if infos, err := checkNginx(client, w.network); err != nil { 63 if err != ErrServiceUnknown { 64 services["nginx"] = err.Error() 65 } 66 } else { 67 services["nginx"] = infos.String() 68 } 69 logger.Debug("Checking for ethstats availability") 70 if infos, err := checkEthstats(client, w.network); err != nil { 71 if err != ErrServiceUnknown { 72 services["ethstats"] = err.Error() 73 } 74 } else { 75 services["ethstats"] = infos.String() 76 protips.ethstats = infos.config 77 } 78 logger.Debug("Checking for bootnode availability") 79 if infos, err := checkNode(client, w.network, true); err != nil { 80 if err != ErrServiceUnknown { 81 services["bootnode"] = err.Error() 82 } 83 } else { 84 services["bootnode"] = infos.String() 85 86 protips.genesis = string(infos.genesis) 87 protips.bootFull = append(protips.bootFull, infos.enodeFull) 88 if infos.enodeLight != "" { 89 protips.bootLight = append(protips.bootLight, infos.enodeLight) 90 } 91 } 92 logger.Debug("Checking for sealnode availability") 93 if infos, err := checkNode(client, w.network, false); err != nil { 94 if err != ErrServiceUnknown { 95 services["sealnode"] = err.Error() 96 } 97 } else { 98 services["sealnode"] = infos.String() 99 protips.genesis = string(infos.genesis) 100 } 101 logger.Debug("Checking for faucet availability") 102 if infos, err := checkFaucet(client, w.network); err != nil { 103 if err != ErrServiceUnknown { 104 services["faucet"] = err.Error() 105 } 106 } else { 107 services["faucet"] = infos.String() 108 } 109 logger.Debug("Checking for dashboard availability") 110 if infos, err := checkDashboard(client, w.network); err != nil { 111 if err != ErrServiceUnknown { 112 services["dashboard"] = err.Error() 113 } 114 } else { 115 services["dashboard"] = infos.String() 116 } 117 // All status checks complete, report and check next server 118 delete(w.services, server) 119 for service := range services { 120 w.services[server] = append(w.services[server], service) 121 } 122 server, address := client.server, client.address 123 for service, status := range services { 124 stats.Append([]string{server, address, "online", service, status}) 125 server, address = "", "" 126 } 127 if len(services) == 0 { 128 stats.Append([]string{server, address, "online", "", ""}) 129 } 130 } 131 // If a genesis block was found, load it into our configs 132 if protips.genesis != "" { 133 genesis := new(core.Genesis) 134 if err := json.Unmarshal([]byte(protips.genesis), genesis); err != nil { 135 log.Error("Failed to parse remote genesis", "err", err) 136 } else { 137 w.conf.genesis = genesis 138 protips.network = genesis.Config.ChainId.Int64() 139 } 140 } 141 if protips.ethstats != "" { 142 w.conf.ethstats = protips.ethstats 143 } 144 w.conf.bootFull = protips.bootFull 145 w.conf.bootLight = protips.bootLight 146 147 // Print any collected stats and return 148 if !tips { 149 stats.Render() 150 } else { 151 protips.print(w.network) 152 } 153 } 154 155 // protips contains a collection of network infos to report pro-tips 156 // based on. 157 type protips struct { 158 genesis string 159 network int64 160 bootFull []string 161 bootLight []string 162 ethstats string 163 } 164 165 // print analyzes the network information available and prints a collection of 166 // pro tips for the user's consideration. 167 func (p *protips) print(network string) { 168 // If a known genesis block is available, display it and prepend an init command 169 fullinit, lightinit := "", "" 170 if p.genesis != "" { 171 fullinit = fmt.Sprintf("gwtc --datadir=$HOME/.%s init %s.json && ", network, network) 172 lightinit = fmt.Sprintf("gwtc --datadir=$HOME/.%s --light init %s.json && ", network, network) 173 } 174 // If an ethstats server is available, add the ethstats flag 175 statsflag := "" 176 if p.ethstats != "" { 177 if strings.Contains(p.ethstats, " ") { 178 statsflag = fmt.Sprintf(` --ethstats="yournode:%s"`, p.ethstats) 179 } else { 180 statsflag = fmt.Sprintf(` --ethstats=yournode:%s`, p.ethstats) 181 } 182 } 183 // If bootnodes have been specified, add the bootnode flag 184 bootflagFull := "" 185 if len(p.bootFull) > 0 { 186 bootflagFull = fmt.Sprintf(` --bootnodes %s`, strings.Join(p.bootFull, ",")) 187 } 188 bootflagLight := "" 189 if len(p.bootLight) > 0 { 190 bootflagLight = fmt.Sprintf(` --bootnodes %s`, strings.Join(p.bootLight, ",")) 191 } 192 // Assemble all the known pro-tips 193 var tasks, tips []string 194 195 tasks = append(tasks, "Run an archive node with historical data") 196 tips = append(tips, fmt.Sprintf("%sgwtc --networkid=%d --datadir=$HOME/.%s --cache=1024%s%s", fullinit, p.network, network, statsflag, bootflagFull)) 197 198 tasks = append(tasks, "Run a full node with recent data only") 199 tips = append(tips, fmt.Sprintf("%sgwtc --networkid=%d --datadir=$HOME/.%s --cache=512 --fast%s%s", fullinit, p.network, network, statsflag, bootflagFull)) 200 201 tasks = append(tasks, "Run a light node with on demand retrievals") 202 tips = append(tips, fmt.Sprintf("%sgwtc --networkid=%d --datadir=$HOME/.%s --light%s%s", lightinit, p.network, network, statsflag, bootflagLight)) 203 204 tasks = append(tasks, "Run an embedded node with constrained memory") 205 tips = append(tips, fmt.Sprintf("%sgwtc --networkid=%d --datadir=$HOME/.%s --cache=32 --light%s%s", lightinit, p.network, network, statsflag, bootflagLight)) 206 207 // If the tips are short, display in a table 208 short := true 209 for _, tip := range tips { 210 if len(tip) > 100 { 211 short = false 212 break 213 } 214 } 215 fmt.Println() 216 if short { 217 howto := tablewriter.NewWriter(os.Stdout) 218 howto.SetHeader([]string{"Fun tasks for you", "Tips on how to"}) 219 howto.SetColWidth(100) 220 221 for i := 0; i < len(tasks); i++ { 222 howto.Append([]string{tasks[i], tips[i]}) 223 } 224 howto.Render() 225 return 226 } 227 // Meh, tips got ugly, split into many lines 228 for i := 0; i < len(tasks); i++ { 229 fmt.Println(tasks[i]) 230 fmt.Println(strings.Repeat("-", len(tasks[i]))) 231 fmt.Println(tips[i]) 232 fmt.Println() 233 fmt.Println() 234 } 235 }