Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #1375 - str4d:1331-node-metrics, r=daira
- Loading branch information
Showing
9 changed files
with
323 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
// Copyright (c) 2016 The Zcash developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include "metrics.h" | ||
|
||
#include "chainparams.h" | ||
#include "ui_interface.h" | ||
#include "util.h" | ||
#include "utiltime.h" | ||
|
||
#include <boost/thread.hpp> | ||
#include <boost/thread/synchronized_value.hpp> | ||
#include <string> | ||
#include <sys/ioctl.h> | ||
|
||
AtomicCounter transactionsValidated; | ||
AtomicCounter ehSolverRuns; | ||
AtomicCounter solutionTargetChecks; | ||
AtomicCounter minedBlocks; | ||
|
||
boost::synchronized_value<std::list<std::string>> messageBox; | ||
boost::synchronized_value<std::string> initMessage; | ||
bool loaded = false; | ||
|
||
static bool metrics_ThreadSafeMessageBox(const std::string& message, | ||
const std::string& caption, | ||
unsigned int style) | ||
{ | ||
std::string strCaption; | ||
// Check for usage of predefined caption | ||
switch (style) { | ||
case CClientUIInterface::MSG_ERROR: | ||
strCaption += _("Error"); | ||
break; | ||
case CClientUIInterface::MSG_WARNING: | ||
strCaption += _("Warning"); | ||
break; | ||
case CClientUIInterface::MSG_INFORMATION: | ||
strCaption += _("Information"); | ||
break; | ||
default: | ||
strCaption += caption; // Use supplied caption (can be empty) | ||
} | ||
|
||
boost::strict_lock_ptr<std::list<std::string>> u = messageBox.synchronize(); | ||
u->push_back(strCaption + ": " + message); | ||
if (u->size() > 5) { | ||
u->pop_back(); | ||
} | ||
} | ||
|
||
static void metrics_InitMessage(const std::string& message) | ||
{ | ||
*initMessage = message; | ||
} | ||
|
||
void ConnectMetricsScreen() | ||
{ | ||
uiInterface.ThreadSafeMessageBox.disconnect_all_slots(); | ||
uiInterface.ThreadSafeMessageBox.connect(metrics_ThreadSafeMessageBox); | ||
uiInterface.InitMessage.disconnect_all_slots(); | ||
uiInterface.InitMessage.connect(metrics_InitMessage); | ||
} | ||
|
||
void printMiningStatus(bool mining) | ||
{ | ||
if (mining) { | ||
int nThreads = GetArg("-genproclimit", 1); | ||
if (nThreads < 0) { | ||
// In regtest threads defaults to 1 | ||
if (Params().DefaultMinerThreads()) | ||
nThreads = Params().DefaultMinerThreads(); | ||
else | ||
nThreads = boost::thread::hardware_concurrency(); | ||
} | ||
std::cout << strprintf(_("You are running %d mining threads."), nThreads) << std::endl; | ||
} else { | ||
std::cout << _("You are currently not mining.") << std::endl; | ||
std::cout << _("To enable mining, add 'gen=1' to your zcash.conf and restart.") << std::endl; | ||
} | ||
std::cout << std::endl; | ||
} | ||
|
||
int printMetrics(size_t cols, int64_t nStart, bool mining) | ||
{ | ||
// Number of lines that are always displayed | ||
int lines = 3; | ||
|
||
// Calculate uptime | ||
int64_t uptime = GetTime() - nStart; | ||
int days = uptime / (24 * 60 * 60); | ||
int hours = (uptime - (days * 24 * 60 * 60)) / (60 * 60); | ||
int minutes = (uptime - (((days * 24) + hours) * 60 * 60)) / 60; | ||
int seconds = uptime - (((((days * 24) + hours) * 60) + minutes) * 60); | ||
|
||
// Display uptime | ||
std::string duration; | ||
if (days > 0) { | ||
duration = strprintf(_("%d days, %d hours, %d minutes, %d seconds"), days, hours, minutes, seconds); | ||
} else if (hours > 0) { | ||
duration = strprintf(_("%d hours, %d minutes, %d seconds"), hours, minutes, seconds); | ||
} else if (minutes > 0) { | ||
duration = strprintf(_("%d minutes, %d seconds"), minutes, seconds); | ||
} else { | ||
duration = strprintf(_("%d seconds"), seconds); | ||
} | ||
std::string strDuration = strprintf(_("Since starting this node %s ago:"), duration); | ||
std::cout << strDuration << std::endl; | ||
lines += (strDuration.size() / cols); | ||
|
||
std::cout << "- " << strprintf(_("You have validated %d transactions!"), transactionsValidated.get()) << std::endl; | ||
|
||
if (mining) { | ||
double solps = uptime > 0 ? (double)solutionTargetChecks.get() / uptime : 0; | ||
std::string strSolps = strprintf("%.4f Sol/s", solps); | ||
std::cout << "- " << strprintf(_("You have contributed %s on average to the network solution rate."), strSolps) << std::endl; | ||
std::cout << "- " << strprintf(_("You have completed %d Equihash solver runs."), ehSolverRuns.get()) << std::endl; | ||
lines += 2; | ||
|
||
int mined = minedBlocks.get(); | ||
if (mined > 0) { | ||
std::cout << "- " << strprintf(_("You have mined %d blocks!"), mined) << std::endl; | ||
lines++; | ||
} | ||
} | ||
std::cout << std::endl; | ||
|
||
return lines; | ||
} | ||
|
||
int printMessageBox(size_t cols) | ||
{ | ||
boost::strict_lock_ptr<std::list<std::string>> u = messageBox.synchronize(); | ||
|
||
if (u->size() == 0) { | ||
return 0; | ||
} | ||
|
||
int lines = 2 + u->size(); | ||
std::cout << _("Messages:") << std::endl; | ||
for (auto it = u->cbegin(); it != u->cend(); ++it) { | ||
std::cout << *it << std::endl; | ||
// Handle wrapped lines | ||
lines += (it->size() / cols); | ||
} | ||
std::cout << std::endl; | ||
return lines; | ||
} | ||
|
||
int printInitMessage() | ||
{ | ||
if (loaded) { | ||
return 0; | ||
} | ||
|
||
std::string msg = *initMessage; | ||
std::cout << _("Init message:") << " " << msg << std::endl; | ||
std::cout << std::endl; | ||
|
||
if (msg == _("Done loading")) { | ||
loaded = true; | ||
} | ||
|
||
return 2; | ||
} | ||
|
||
void ThreadShowMetricsScreen() | ||
{ | ||
// Make this thread recognisable as the metrics screen thread | ||
RenameThread("zcash-metrics-screen"); | ||
|
||
// Clear screen | ||
std::cout << "\e[2J"; | ||
|
||
// Print art | ||
std::cout << METRICS_ART << std::endl; | ||
std::cout << std::endl; | ||
|
||
// Thank you text | ||
std::cout << _("Thank you for running a Zcash node!") << std::endl; | ||
std::cout << _("You're helping to strengthen the network and contributing to a social good :)") << std::endl; | ||
std::cout << std::endl; | ||
|
||
// Miner status | ||
bool mining = GetBoolArg("-gen", false); | ||
printMiningStatus(mining); | ||
|
||
// Count uptime | ||
int64_t nStart = GetTime(); | ||
|
||
while (true) { | ||
// Number of lines that are always displayed | ||
int lines = 1; | ||
|
||
// Get current window size | ||
struct winsize w; | ||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); | ||
|
||
// Erase below current position | ||
std::cout << "\e[J"; | ||
|
||
lines += printMetrics(w.ws_col, nStart, mining); | ||
lines += printMessageBox(w.ws_col); | ||
lines += printInitMessage(); | ||
|
||
// Explain how to exit | ||
std::cout << "[" << _("Press Ctrl+C to exit") << "] [" << _("Set 'showmetrics=0' to hide") << "]" << std::endl;; | ||
|
||
boost::this_thread::interruption_point(); | ||
MilliSleep(1000); | ||
|
||
// Return to the top of the updating section | ||
std::cout << "\e[" << lines << "A"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (c) 2016 The Zcash developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include <atomic> | ||
#include <string> | ||
|
||
struct AtomicCounter { | ||
std::atomic<int> value; | ||
|
||
AtomicCounter() : value {0} { } | ||
|
||
void increment(){ | ||
++value; | ||
} | ||
|
||
void decrement(){ | ||
--value; | ||
} | ||
|
||
int get(){ | ||
return value.load(); | ||
} | ||
}; | ||
|
||
extern AtomicCounter transactionsValidated; | ||
extern AtomicCounter ehSolverRuns; | ||
extern AtomicCounter solutionTargetChecks; | ||
extern AtomicCounter minedBlocks; | ||
|
||
void ConnectMetricsScreen(); | ||
void ThreadShowMetricsScreen(); | ||
|
||
/** | ||
* Heart image: https://commons.wikimedia.org/wiki/File:Heart_coraz%C3%B3n.svg | ||
* License: CC BY-SA 3.0 | ||
* | ||
* Rendering options: | ||
* Zcash: img2txt -W 40 -H 20 -f utf8 -d none -g 0.7 Z-yellow.orange-logo.png | ||
* Heart: img2txt -W 40 -H 20 -f utf8 -d none 2000px-Heart_corazón.svg.png | ||
*/ | ||
const std::string METRICS_ART = | ||
" [0;34;40m [0m \n" | ||
" [0;34;40m [0m \n" | ||
" [0;34;40m [0;31;40m:8[0;33;5;40;100m8[0;1;30;90;43mSX@888@@X[0;31;5;40;100m8[0;31;40m:[0;34;40m [0m [0;31;5;41;101m8; %[0;1;31;91;41mX[0m [0;1;31;91;41mX[0;31;5;41;101m% ;8[0m \n" | ||
" [0;34;40m [0;31;40m%[0;1;30;90;43m%X[0;1;33;93;43mt[0;33;5;43;103m%tt%[0;1;30;90;43mSSSS[0;33;5;43;103mS:[0;37;5;43;103mXXX[0;1;33;93;43mt[0;1;30;90;43m@[0;31;40m@[0;34;40m [0m [0;1;31;91;41mX[0;31;5;41;101m :[0;1;31;91;41m:[0m [0;1;31;91;41m:[0;31;5;41;101m: [0;1;31;91;41mX[0m \n" | ||
" [0;34;40m [0;31;40m@[0;1;30;90;43mS[0;1;33;93;43m;;tt%%[0;33;5;43;103m%[0;1;33;93;43mt[0;34;40m [0;1;33;93;43m;[0;33;5;43;103m;::[0;37;5;43;103mXXXX[0;37;43mS[0;31;5;40;100mX[0;34;40m [0m [0;31;5;41;101m% SS %[0m \n" | ||
" [0;34;40m [0;31;40m.[0;1;30;90;43mt[0;1;33;93;43m:::;;[0;1;30;90;43m%[0;31;40m8888[0;34;40m [0;31;40m8[0;30;41m8888[0;1;33;93;43mt[0;37;5;43;103mXXXX[0;1;30;90;43m8[0;31;40m;[0;34;40m [0m [0;1;31;91;41mS[0;31;5;41;101m [0;1;31;91;41mS[0m \n" | ||
" [0;34;40m [0;31;40m.[0;1;30;90;43m%[0;1;33;93;43m...:::[0;31;40m8[0;34;40m [0;1;30;90;43m8[0;33;5;43;103m::[0;37;5;43;103mXXX[0;1;33;93;43m%[0;31;40m;[0;34;40m [0m [0;31;5;41;101mX X[0m \n" | ||
" [0;34;40m [0;31;43m8[0;1;31;91;43m888[0;1;33;93;43m...:[0;1;30;90;43mt[0;1;30;90;41m888888[0;31;40mX[0;34;40m [0;33;5;40;100m8[0;33;5;43;103mt;;::[0;37;5;43;103mXX[0;1;30;90;43m8[0;31;40m [0;34;40m [0m [0;31;5;41;101m8 8[0m \n" | ||
"[0;34;40m [0;31;40m%[0;1;31;91;43m888888[0;1;33;93;43m...:::;:[0;1;30;90;41m8[0;31;40m [0;34;40m [0;31;40m:[0;1;30;90;43mX[0;33;5;43;103mttt;;;::[0;37;5;43;103mX[0;31;5;40;100m@[0;34;40m [0m [0;31;5;41;101m [0m \n" | ||
"[0;34;40m [0;1;30;90;41m8[0;1;31;91;43m88888888[0;1;33;93;43m...:[0;1;30;90;43mS[0;31;40mt[0;34;40m [0;1;30;90;41m8[0;1;33;93;43m:%[0;33;5;43;103m%tttt;;;:[0;1;30;90;43mX[0;34;40m [0m [0;31;5;41;101mX X[0m \n" | ||
"[0;34;40m [0;1;30;90;41m8[0;1;31;91;43m8888888888[0;1;30;90;43mS[0;1;30;90;41m8[0;31;40m [0;34;40m [0;31;40m:[0;1;30;90;43m%[0;1;33;93;43m;ttt%[0;33;5;43;103m%tttt;;[0;1;30;90;43mX[0;34;40m [0m [0;31;5;41;101m8 8[0m \n" | ||
"[0;34;40m [0;31;40m%[0;1;31;91;43m888888888[0;1;30;90;43m%[0;31;40mt[0;34;40m [0;30;41m8[0;1;30;90;43mS[0;1;33;93;43m:;;;tt%%[0;33;5;43;103m%ttt;[0;1;30;90;41m8[0;34;40m [0m [0;31;5;41;101m: :[0m \n" | ||
" [0;34;40m [0;31;43m8t[0;1;31;91;43m888888[0;33;41m8[0;31;40m [0;34;40m [0;31;40mS[0;33;41m888[0;31;43m8888[0;1;30;90;43mS[0;1;33;93;43mtt%%[0;33;5;43;103m%t[0;1;30;90;43m@[0;31;40m [0;34;40m [0m [0;1;31;91;41m:[0;31;5;41;101m: :[0;1;31;91;41m:[0m \n" | ||
" [0;34;40m [0;31;40m.[0;31;43m@tt[0;1;31;91;43m888[0;31;43m@[0;34;40m [0;1;30;90;41m8[0;1;33;93;43m;;ttt[0;1;30;90;43m@[0;31;40m;[0;34;40m [0m [0;31;5;41;101mt t[0m \n" | ||
" [0;34;40m [0;31;40m.[0;31;43m8ttt[0;1;31;91;43m8[0;31;43m@[0;31;40mSSSSS[0;34;40m [0;31;40mSXXXX[0;1;30;90;43m%[0;1;33;93;43m:;;;[0;1;30;90;43mX[0;31;40m;[0;34;40m [0m [0;31;5;41;101m8 8[0m \n" | ||
" [0;34;40m [0;31;40mX[0;31;43m8ttt[0;1;31;91;43m8888[0;1;30;90;43m%[0;34;40m [0;1;30;90;43m%[0;1;31;91;43m88[0;1;33;93;43m...::[0;1;30;90;43mX[0;30;41m8[0;31;40m [0;34;40m [0m [0;1;31;91;41mX[0;31;5;41;101m. .[0;1;31;91;41mX[0m \n" | ||
" [0;34;40m [0;31;40m%[0;1;30;90;41m8[0;31;43m@tt[0;1;31;91;43m88[0;31;43m;[0;33;41m8888[0;1;30;90;43m%[0;1;31;91;43m8888[0;1;30;90;43m%[0;31;43m8[0;31;40mX[0;32;40m [0;34;40m [0m [0;1;31;91;41m:[0;31;5;41;101m; ;[0;1;31;91;41m:[0m \n" | ||
" [0;34;40m [0;31;40m:@[0;1;30;90;41m8[0;33;41m8[0;31;43m8@XXX@8[0;1;30;90;41m8[0;31;40m8:[0;34;40m [0m [0;31;5;41;101mtt[0m \n" | ||
" [0;34;40m [0m \n" | ||
" [0;34;40m [0m "; |
Oops, something went wrong.