From 527b557f9e0e2112dfdce8d16b31c67692eb3619 Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Mon, 23 Jul 2018 17:36:23 +0200 Subject: [PATCH 1/9] WIP --- src/App.cpp | 2 +- src/Options.cpp | 17 +---------------- src/Options.h | 2 -- src/cc/Service.cpp | 32 ++++++++++++++++++++++++++++---- src/cc/Service.h | 2 ++ src/log/RemoteLog.cpp | 36 +++++++++++++++++++++--------------- src/log/RemoteLog.h | 9 +++++---- 7 files changed, 58 insertions(+), 42 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 53c10f21..04ad9dde 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -90,7 +90,7 @@ App::App(int argc, char **argv) : } if (m_options->ccUseRemoteLogging()) { - Log::add(new RemoteLog(m_options->ccRemoteLoggingMaxRows())); + Log::add(new RemoteLog()); } # ifdef HAVE_SYSLOG_H diff --git a/src/Options.cpp b/src/Options.cpp index 11812ddd..0fa73004 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -97,8 +97,7 @@ Options:\n" --cc-access-token=T access token for CC Server\n\ --cc-worker-id=ID custom worker-id for CC Server\n\ --cc-update-interval-s=N status update interval in seconds (default: 10 min: 1)\n\ - --cc-use-remote-logging enable remote logging on CC Server\n\ - --cc-remote-logging-max-rows=N maximum last n-log rows to send CC Server\n" + --cc-use-remote-logging enable remote logging on CC Server\n" # endif # endif @@ -183,7 +182,6 @@ static struct option const options[] = { { "cc-key-file", 1, nullptr, 4015 }, { "cc-use-tls", 0, nullptr, 4016 }, { "cc-use-remote-logging", 0, nullptr, 4017 }, - { "cc-remote-logging-max-rows", 1, nullptr, 4018 }, { "daemonized", 0, nullptr, 4011 }, { "doublehash-thread-mask", 1, nullptr, 4013 }, { "multihash-thread-mask", 1, nullptr, 4013 }, @@ -246,7 +244,6 @@ static struct option const cc_client_options[] = { { "update-interval-s", 1, nullptr, 4012 }, { "use-tls", 0, nullptr, 4016 }, { "use-remote-logging", 0, nullptr, 4017 }, - { "remote-logging-max-rows",1, nullptr, 4018 }, { nullptr, 0, nullptr, 0 } }; @@ -349,7 +346,6 @@ Options::Options(int argc, char **argv) : m_threads(0), m_ccUpdateInterval(10), m_ccPort(0), - m_ccRemoteLoggingMaxRows(25), m_affinity(-1L), m_multiHashThreadMask(-1L) { @@ -562,8 +558,6 @@ bool Options::parseArg(int key, const char *arg) case 4006: /* --cc-port */ case 4012: /* --cc-update-interval-c */ return parseArg(key, strtol(arg, nullptr, 10)); - case 4018: /* --cc-remote-logging-max-rows */ - return parseArg(key, strtol(arg, nullptr, 25)); case 'B': /* --background */ case 'k': /* --keepalive */ @@ -762,15 +756,6 @@ bool Options::parseArg(int key, uint64_t arg) } break; - case 4018: /* --cc-remote-logging-max-rows */ - if (arg < 1) { - m_ccUseRemoteLogging = false; - } - else { - m_ccRemoteLoggingMaxRows = (int) arg; - } - break; - default: break; } diff --git a/src/Options.h b/src/Options.h index 197092a3..911b508a 100644 --- a/src/Options.h +++ b/src/Options.h @@ -101,7 +101,6 @@ public: inline size_t threads() const { return m_threads; } inline int ccUpdateInterval() const { return m_ccUpdateInterval; } inline int ccPort() const { return m_ccPort; } - inline size_t ccRemoteLoggingMaxRows() const { return m_ccRemoteLoggingMaxRows; } inline int64_t affinity() const { return m_affinity; } inline int64_t multiHashThreadMask() const { return m_multiHashThreadMask; } inline void setColors(bool colors) { m_colors = colors; } @@ -176,7 +175,6 @@ private: size_t m_threads; int m_ccUpdateInterval; int m_ccPort; - size_t m_ccRemoteLoggingMaxRows; int64_t m_affinity; int64_t m_multiHashThreadMask; std::vector m_pools; diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp index b649cc7f..72719e13 100644 --- a/src/cc/Service.cpp +++ b/src/cc/Service.cpp @@ -40,6 +40,8 @@ uv_mutex_t Service::m_mutex; std::map Service::m_clientCommand; std::map Service::m_clientStatus; +std::map> Service::m_remoteLog; + int Service::m_currentServerTime = 0; bool Service::start() @@ -55,6 +57,7 @@ void Service::release() m_clientCommand.clear(); m_clientStatus.clear(); + m_remoteLog.clear(); uv_mutex_unlock(&m_mutex); } @@ -77,6 +80,8 @@ unsigned Service::handleGET(const Options* options, const std::string& url, cons resultCode = getClientConfig(options, clientId, resp); } else if (url.rfind("/admin/getClientCommand", 0) == 0) { resultCode = getClientCommand(clientId, resp); + } else if (url.rfind("/admin/getClientLog", 0) == 0) { + //resultCode = getClientCommand(clientId, resp); } } else { @@ -228,10 +233,6 @@ unsigned Service::setClientStatus(const std::string& clientIp, const std::string clientStatus.parseFromJson(document); clientStatus.setExternalIp(clientIp); - if (m_clientStatus.find(clientId) == m_clientStatus.end()) { - m_clientCommand[clientId] = ControlCommand(ControlCommand::RESTART); - } - m_clientStatus[clientId] = clientStatus; resultCode = getClientCommand(clientId, resp); @@ -293,6 +294,29 @@ unsigned Service::resetClientStatusList(const std::string& data, std::string& re return MHD_HTTP_OK; } +unsigned Service::getClientLog(const std::string& clientId, std::string& resp) +{ + if (m_remoteLog.find(clientId) != m_remoteLog.end()) { + + rapidjson::Document respDocument; + respDocument.SetObject(); + + auto& allocator = respDocument.GetAllocator(); + + rapidjson::Value controlCommand = m_clientCommand[clientId].toJson(allocator); + respDocument.AddMember("client_log", controlCommand, allocator); + + rapidjson::StringBuffer buffer(0, 4096); + rapidjson::Writer writer(buffer); + writer.SetMaxDecimalPlaces(10); + respDocument.Accept(writer); + + resp = buffer.GetString(); + } + + return MHD_HTTP_OK; +} + unsigned Service::getAdminPage(const Options* options, std::string& resp) { std::stringstream data; diff --git a/src/cc/Service.h b/src/cc/Service.h index 4993e978..98d0ee03 100644 --- a/src/cc/Service.h +++ b/src/cc/Service.h @@ -48,6 +48,7 @@ public: private: static unsigned getClientConfig(const Options* options, const std::string& clientId, std::string& resp); static unsigned getClientCommand(const std::string& clientId, std::string& resp); + static unsigned getClientLog(const std::string& clientId, std::string& resp); static unsigned getClientStatusList(std::string& resp); static unsigned getAdminPage(const Options* options, std::string& resp); @@ -63,6 +64,7 @@ private: static std::map m_clientStatus; static std::map m_clientCommand; + static std::map> m_remoteLog; static uv_mutex_t m_mutex; diff --git a/src/log/RemoteLog.cpp b/src/log/RemoteLog.cpp index 7a314790..d0d93caa 100644 --- a/src/log/RemoteLog.cpp +++ b/src/log/RemoteLog.cpp @@ -22,15 +22,19 @@ RemoteLog* RemoteLog::m_self = nullptr; -RemoteLog::RemoteLog(size_t maxRows) - : maxRows_(maxRows) +RemoteLog::RemoteLog() + : m_maxRows(100) { + uv_mutex_init(&m_mutex); + m_self = this; } RemoteLog::~RemoteLog() { m_self = nullptr; + + uv_mutex_destroy(&m_mutex); } void RemoteLog::message(int level, const char* fmt, va_list args) @@ -56,13 +60,17 @@ void RemoteLog::message(int level, const char* fmt, va_list args) size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size; buf[size] = '\n'; - if (rows_.size() == maxRows_) { - rows_.pop_front(); + uv_mutex_lock(&m_mutex); + + if (m_rows.size() == m_maxRows) { + m_rows.pop_front(); } std::string row = std::regex_replace(std::string(buf, size+1), std::regex("\x1B\\[[0-9;]*[a-zA-Z]"), ""); - rows_.push_back(row); + m_rows.push_back(row); + + uv_mutex_unlock(&m_mutex); delete[](buf); } @@ -73,23 +81,21 @@ void RemoteLog::text(const char* fmt, va_list args) message(0, fmt, args); } -void RemoteLog::flushRows() -{ - if (m_self) { - m_self->rows_.clear(); - } -} - - std::string RemoteLog::getRows() { std::stringstream data; + uv_mutex_lock(&m_self->m_mutex); + if (m_self) { - for (std::list::iterator it = m_self->rows_.begin(); it != m_self->rows_.end(); it++) { - data << it->c_str(); + for (auto& m_row : m_self->m_rows) { + data << m_row.c_str(); } } + m_self->m_rows.clear(); + + uv_mutex_unlock(&m_self->m_mutex); + return data.str(); } diff --git a/src/log/RemoteLog.h b/src/log/RemoteLog.h index 793e01ba..07e8a768 100644 --- a/src/log/RemoteLog.h +++ b/src/log/RemoteLog.h @@ -21,6 +21,7 @@ #include #include +#include #include "interfaces/ILogBackend.h" @@ -28,21 +29,21 @@ class RemoteLog : public ILogBackend { public: - RemoteLog(size_t maxRows); + RemoteLog(); ~RemoteLog(); void message(int level, const char* fmt, va_list args) override; void text(const char* fmt, va_list args) override; - static void flushRows(); static std::string getRows(); private: static RemoteLog* m_self; - size_t maxRows_; - std::list rows_; + uv_mutex_t m_mutex; + size_t m_maxRows; + std::list m_rows; }; #endif /* __REMOTELOG_H__ */ From ed80e8a43643c8a55080414ff9d11ed846517dbf Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Fri, 27 Jul 2018 17:18:57 +0200 Subject: [PATCH 2/9] WIP --- index.html | 37 +++++++++++----- src/App.cpp | 3 +- src/Options.cpp | 10 +++++ src/Options.h | 2 + src/cc/ClientStatus.cpp | 5 +++ src/cc/ClientStatus.h | 3 +- src/cc/Service.cpp | 93 +++++++++++++++++++++++++++-------------- src/cc/Service.h | 6 ++- src/config_cc.json | 1 + src/log/Log.cpp | 1 - src/log/RemoteLog.cpp | 4 +- src/log/RemoteLog.h | 2 +- 12 files changed, 117 insertions(+), 50 deletions(-) diff --git a/index.html b/index.html index 2c6d5613..934a6d3f 100644 --- a/index.html +++ b/index.html @@ -411,15 +411,24 @@ var data = table.row( $(this).parents('tr') ).data(); var clientId = data['client_status']['client_id']; var clientIp = data['client_status']['external_ip']; - var log = data['client_status']['log']; - var htmlContent = "
" + - ""+ - "" + - "
"; + $.ajax({ + type: "GET", + url: "/admin/getClientLog?clientId=" + clientId, + dataType:"json", + success: function(jsonClientLog) { + var htmlContent = "
" + + ""+ + "" + + "
"; - $('#minerLog').find('.modal-body').html(htmlContent); - $('#minerLog').modal('show'); + $('#minerLog').find('.modal-body').html(htmlContent); + $('#minerLog').modal('show'); + }, + error: function (data) { + setError('Unable to fetch ' + clientId + ' log. - Please make sure it is enabled on the miner!'); + } + }); }); $('#minerLogRefresh').click(function(event) { @@ -429,9 +438,17 @@ var row = table.row(index); var data = row.data(); - if (clientId === data.client_status.client_id) { - $('#log').val(data.client_status.log); - } + $.ajax({ + type: "GET", + url: "/admin/getClientLog?clientId=" + clientId, + dataType:"json", + success: function(jsonClientLog) { + $('#log').val(JSON.stringify(jsonClientLog,undefined, 2)); + }, + error: function (data) { + setError('Unable to fetch ' + clientId + ' log. - Please make sure it is enabled on the miner!'); + } + }); }); }); diff --git a/src/App.cpp b/src/App.cpp index 04ad9dde..0b549eda 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -90,7 +90,8 @@ App::App(int argc, char **argv) : } if (m_options->ccUseRemoteLogging()) { - Log::add(new RemoteLog()); + // 20 lines per second should be enough + Log::add(new RemoteLog(static_cast(m_options->ccUpdateInterval() * 20))); } # ifdef HAVE_SYSLOG_H diff --git a/src/Options.cpp b/src/Options.cpp index 0fa73004..7392eb13 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -110,6 +110,7 @@ Options:\n" --cc-use-tls enable tls encryption for CC communication\n\ --cc-cert-file=FILE when tls is turned on, use this to point to the right cert file (default: server.pem) \n\ --cc-key-file=FILE when tls is turned on, use this to point to the right key file (default: server.key) \n\ + --client-log-lines-history=N maximum lines of log history kept per miner \n\ --cc-client-config-folder=FOLDER Folder contains the client config files\n\ --cc-custom-dashboard=FILE loads a custom dashboard and serve it to '/'\n" # endif @@ -182,6 +183,7 @@ static struct option const options[] = { { "cc-key-file", 1, nullptr, 4015 }, { "cc-use-tls", 0, nullptr, 4016 }, { "cc-use-remote-logging", 0, nullptr, 4017 }, + { "cc-client-log-lines-history", 1, nullptr, 4018 }, { "daemonized", 0, nullptr, 4011 }, { "doublehash-thread-mask", 1, nullptr, 4013 }, { "multihash-thread-mask", 1, nullptr, 4013 }, @@ -257,6 +259,7 @@ static struct option const cc_server_options[] = { { "cert-file", 1, nullptr, 4014 }, { "key-file", 1, nullptr, 4015 }, { "use-tls", 0, nullptr, 4016 }, + { "client-log-lines-history", 1, nullptr, 4018 }, { nullptr, 0, nullptr, 0 } }; @@ -346,6 +349,7 @@ Options::Options(int argc, char **argv) : m_threads(0), m_ccUpdateInterval(10), m_ccPort(0), + m_ccClientLogLinesHistory(100), m_affinity(-1L), m_multiHashThreadMask(-1L) { @@ -558,6 +562,8 @@ bool Options::parseArg(int key, const char *arg) case 4006: /* --cc-port */ case 4012: /* --cc-update-interval-c */ return parseArg(key, strtol(arg, nullptr, 10)); + case 4018: /* --cc-client-log-lines-history */ + return parseArg(key, strtol(arg, nullptr, 25)); case 'B': /* --background */ case 'k': /* --keepalive */ @@ -756,6 +762,10 @@ bool Options::parseArg(int key, uint64_t arg) } break; + case 4018: /* --cc-client-log-lines-history */ + m_ccClientLogLinesHistory = (int) arg; + break; + default: break; } diff --git a/src/Options.h b/src/Options.h index 911b508a..cc89e887 100644 --- a/src/Options.h +++ b/src/Options.h @@ -101,6 +101,7 @@ public: inline size_t threads() const { return m_threads; } inline int ccUpdateInterval() const { return m_ccUpdateInterval; } inline int ccPort() const { return m_ccPort; } + inline size_t ccClientLogLinesHistory() const { return m_ccClientLogLinesHistory; } inline int64_t affinity() const { return m_affinity; } inline int64_t multiHashThreadMask() const { return m_multiHashThreadMask; } inline void setColors(bool colors) { m_colors = colors; } @@ -175,6 +176,7 @@ private: size_t m_threads; int m_ccUpdateInterval; int m_ccPort; + size_t m_ccClientLogLinesHistory; int64_t m_affinity; int64_t m_multiHashThreadMask; std::vector m_pools; diff --git a/src/cc/ClientStatus.cpp b/src/cc/ClientStatus.cpp index 1a040907..cddb8c89 100644 --- a/src/cc/ClientStatus.cpp +++ b/src/cc/ClientStatus.cpp @@ -150,6 +150,11 @@ void ClientStatus::setLog(const std::string& log) m_log = log; } +void ClientStatus::clearLog() +{ + m_log.clear(); +} + bool ClientStatus::hasHugepages() const { return m_hasHugepages; diff --git a/src/cc/ClientStatus.h b/src/cc/ClientStatus.h index 66a9b6f2..e8204126 100644 --- a/src/cc/ClientStatus.h +++ b/src/cc/ClientStatus.h @@ -82,7 +82,8 @@ public: void setVersion(const std::string& version); std::string getLog() const; - void setLog(const std::string& version); + void setLog(const std::string& log); + void clearLog(); bool hasHugepages() const; void setHugepages(bool hasHugepages); diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp index 72719e13..6c9e317b 100644 --- a/src/cc/Service.cpp +++ b/src/cc/Service.cpp @@ -40,7 +40,7 @@ uv_mutex_t Service::m_mutex; std::map Service::m_clientCommand; std::map Service::m_clientStatus; -std::map> Service::m_remoteLog; +std::map> Service::m_clientLog; int Service::m_currentServerTime = 0; @@ -57,7 +57,7 @@ void Service::release() m_clientCommand.clear(); m_clientStatus.clear(); - m_remoteLog.clear(); + m_clientLog.clear(); uv_mutex_unlock(&m_mutex); } @@ -81,7 +81,7 @@ unsigned Service::handleGET(const Options* options, const std::string& url, cons } else if (url.rfind("/admin/getClientCommand", 0) == 0) { resultCode = getClientCommand(clientId, resp); } else if (url.rfind("/admin/getClientLog", 0) == 0) { - //resultCode = getClientCommand(clientId, resp); + resultCode = getClientLog(clientId, resp); } } else { @@ -105,7 +105,7 @@ unsigned Service::handlePOST(const Options* options, const std::string& url, con url.c_str(), clientIp.c_str(), clientId.c_str(), data.length()); if (url.rfind("/client/setClientStatus", 0) == 0) { - resultCode = setClientStatus(clientIp, clientId, data, resp); + resultCode = setClientStatus(options, clientIp, clientId, data, resp); } else if (url.rfind("/admin/setClientConfig", 0) == 0 || url.rfind("/client/setClientConfig", 0) == 0) { resultCode = setClientConfig(options, clientId, data, resp); } else if (url.rfind("/admin/setClientCommand", 0) == 0) { @@ -221,7 +221,7 @@ unsigned Service::getClientStatusList(std::string& resp) return MHD_HTTP_OK; } -unsigned Service::setClientStatus(const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp) +unsigned Service::setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp) { int resultCode = MHD_HTTP_BAD_REQUEST; @@ -233,6 +233,10 @@ unsigned Service::setClientStatus(const std::string& clientIp, const std::string clientStatus.parseFromJson(document); clientStatus.setExternalIp(clientIp); + setClientLog(options->ccClientLogLinesHistory(), clientId, clientStatus.getLog()); + + clientStatus.clearLog(); + m_clientStatus[clientId] = clientStatus; resultCode = getClientCommand(clientId, resp); @@ -271,40 +275,22 @@ unsigned Service::getClientCommand(const std::string& clientId, std::string& res return MHD_HTTP_OK; } -unsigned Service::setClientCommand(const std::string& clientId, const std::string& data, std::string& resp) -{ - ControlCommand controlCommand; - - rapidjson::Document document; - if (!document.Parse(data.c_str()).HasParseError()) { - controlCommand.parseFromJson(document); - - m_clientCommand[clientId] = controlCommand; - - return MHD_HTTP_OK; - } else { - return MHD_HTTP_BAD_REQUEST; - } -} - -unsigned Service::resetClientStatusList(const std::string& data, std::string& resp) -{ - m_clientStatus.clear(); - - return MHD_HTTP_OK; -} - unsigned Service::getClientLog(const std::string& clientId, std::string& resp) { - if (m_remoteLog.find(clientId) != m_remoteLog.end()) { - + if (m_clientLog.find(clientId) != m_clientLog.end()) { rapidjson::Document respDocument; respDocument.SetObject(); auto& allocator = respDocument.GetAllocator(); - rapidjson::Value controlCommand = m_clientCommand[clientId].toJson(allocator); - respDocument.AddMember("client_log", controlCommand, allocator); + std::stringstream data; + for (auto& m_row : m_clientLog[clientId]) { + data << m_row.c_str() << std::endl; + } + + LOG_INFO("LOG: %s", data.str().c_str()); + + respDocument.AddMember("client_log", rapidjson::StringRef(data.str().c_str()), allocator); rapidjson::StringBuffer buffer(0, 4096); rapidjson::Writer writer(buffer); @@ -351,6 +337,49 @@ unsigned Service::getAdminPage(const Options* options, std::string& resp) return MHD_HTTP_OK; } +unsigned Service::setClientCommand(const std::string& clientId, const std::string& data, std::string& resp) +{ + ControlCommand controlCommand; + + rapidjson::Document document; + if (!document.Parse(data.c_str()).HasParseError()) { + controlCommand.parseFromJson(document); + + m_clientCommand[clientId] = controlCommand; + + return MHD_HTTP_OK; + } else { + return MHD_HTTP_BAD_REQUEST; + } +} + +void Service::setClientLog(size_t maxRows, const std::string& clientId, const std::string& log) +{ + if (m_clientLog.find(clientId) == m_clientLog.end()) { + m_clientLog[clientId] = std::list(); + } + + auto* clientLog = &m_clientLog[clientId]; + std::istringstream logStream(log); + + std::string logLine; + while (std::getline(logStream, logLine)) + { + if (clientLog->size() == maxRows) { + clientLog->pop_front(); + } + + clientLog->push_back(logLine); + } +} + +unsigned Service::resetClientStatusList(const std::string& data, std::string& resp) +{ + m_clientStatus.clear(); + + return MHD_HTTP_OK; +} + std::string Service::getClientConfigFileName(const Options* options, const std::string& clientId) { std::string clientConfigFileName; diff --git a/src/cc/Service.h b/src/cc/Service.h index 98d0ee03..e909debd 100644 --- a/src/cc/Service.h +++ b/src/cc/Service.h @@ -52,11 +52,13 @@ private: static unsigned getClientStatusList(std::string& resp); static unsigned getAdminPage(const Options* options, std::string& resp); - static unsigned setClientStatus(const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp); + static unsigned setClientStatus(const Options* options, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp); static unsigned setClientCommand(const std::string& clientId, const std::string& data, std::string& resp); static unsigned setClientConfig(const Options* options, const std::string &clientId, const std::string &data, std::string &resp); static unsigned resetClientStatusList(const std::string& data, std::string& resp); + static void setClientLog(size_t maxRows, const std::string& clientId, const std::string& log); + static std::string getClientConfigFileName(const Options *options, const std::string &clientId); private: @@ -64,7 +66,7 @@ private: static std::map m_clientStatus; static std::map m_clientCommand; - static std::map> m_remoteLog; + static std::map> m_clientLog; static uv_mutex_t m_mutex; diff --git a/src/config_cc.json b/src/config_cc.json index 2b716a0d..ea4e492a 100644 --- a/src/config_cc.json +++ b/src/config_cc.json @@ -12,6 +12,7 @@ "user": "admin", // admin user for access CC Dashboard "pass": "pass", // admin pass for access CC Dashboard "client-config-folder" : null, // folder which contains the client-config files (null=current) + "client-log-lines-history" : 100, // maximum lines of log history kept per miner "custom-dashboard" : "index.html" // dashboard html file } } diff --git a/src/log/Log.cpp b/src/log/Log.cpp index f37d4424..906ddf17 100644 --- a/src/log/Log.cpp +++ b/src/log/Log.cpp @@ -35,7 +35,6 @@ Log *Log::m_self = nullptr; - Log::Log() { uv_mutex_init(&m_mutex); diff --git a/src/log/RemoteLog.cpp b/src/log/RemoteLog.cpp index d0d93caa..f5552d09 100644 --- a/src/log/RemoteLog.cpp +++ b/src/log/RemoteLog.cpp @@ -22,8 +22,8 @@ RemoteLog* RemoteLog::m_self = nullptr; -RemoteLog::RemoteLog() - : m_maxRows(100) +RemoteLog::RemoteLog(size_t maxRows) + : m_maxRows(maxRows) { uv_mutex_init(&m_mutex); diff --git a/src/log/RemoteLog.h b/src/log/RemoteLog.h index 07e8a768..973cc8f5 100644 --- a/src/log/RemoteLog.h +++ b/src/log/RemoteLog.h @@ -29,7 +29,7 @@ class RemoteLog : public ILogBackend { public: - RemoteLog(); + RemoteLog(size_t maxRows); ~RemoteLog(); void message(int level, const char* fmt, va_list args) override; From 9380880b587b3f57681ef6fc38b7e7b6ac22065b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ben=20Gr=C3=A4f?= Date: Fri, 27 Jul 2018 21:21:33 +0200 Subject: [PATCH 3/9] Fix getClientLogs function and log viewer on dashboard --- index.html | 8 ++++---- src/cc/Service.cpp | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index 934a6d3f..29ebd37d 100644 --- a/index.html +++ b/index.html @@ -416,10 +416,10 @@ type: "GET", url: "/admin/getClientLog?clientId=" + clientId, dataType:"json", - success: function(jsonClientLog) { + success: function(data) { var htmlContent = "
" + ""+ - "" + + "" + "
"; $('#minerLog').find('.modal-body').html(htmlContent); @@ -442,8 +442,8 @@ type: "GET", url: "/admin/getClientLog?clientId=" + clientId, dataType:"json", - success: function(jsonClientLog) { - $('#log').val(JSON.stringify(jsonClientLog,undefined, 2)); + success: function(data) { + $('#log').val(data.client_log); }, error: function (data) { setError('Unable to fetch ' + clientId + ' log. - Please make sure it is enabled on the miner!'); diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp index 6c9e317b..a12d44be 100644 --- a/src/cc/Service.cpp +++ b/src/cc/Service.cpp @@ -288,9 +288,8 @@ unsigned Service::getClientLog(const std::string& clientId, std::string& resp) data << m_row.c_str() << std::endl; } - LOG_INFO("LOG: %s", data.str().c_str()); - - respDocument.AddMember("client_log", rapidjson::StringRef(data.str().c_str()), allocator); + std::string log = data.str(); + respDocument.AddMember("client_log", rapidjson::StringRef(log.c_str()), allocator); rapidjson::StringBuffer buffer(0, 4096); rapidjson::Writer writer(buffer); From 4ae65643bab9d8feb54d84940c0ef792c5e59f2b Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Thu, 2 Aug 2018 13:57:07 +0200 Subject: [PATCH 4/9] Add config property to enable/disable config upload on startup --- src/Options.cpp | 15 +++++++++++++-- src/Options.h | 2 ++ src/cc/CCClient.cpp | 4 +++- src/cc/Service.cpp | 2 -- src/config.json | 3 ++- src/default_config.json | 5 +++-- src/version.h | 4 ++-- 7 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 7392eb13..9b24e6ae 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -97,7 +97,8 @@ Options:\n" --cc-access-token=T access token for CC Server\n\ --cc-worker-id=ID custom worker-id for CC Server\n\ --cc-update-interval-s=N status update interval in seconds (default: 10 min: 1)\n\ - --cc-use-remote-logging enable remote logging on CC Server\n" + --cc-use-remote-logging enable remote logging on CC Server\n\ + --cc-upload-config-on-startup upload current miner config to CC Server on startup\n" # endif # endif @@ -182,8 +183,9 @@ static struct option const options[] = { { "cc-cert-file", 1, nullptr, 4014 }, { "cc-key-file", 1, nullptr, 4015 }, { "cc-use-tls", 0, nullptr, 4016 }, - { "cc-use-remote-logging", 0, nullptr, 4017 }, + { "cc-use-remote-logging", 0, nullptr, 4017 }, { "cc-client-log-lines-history", 1, nullptr, 4018 }, + { "cc-upload-config-on-startup", 0, nullptr, 4019 }, { "daemonized", 0, nullptr, 4011 }, { "doublehash-thread-mask", 1, nullptr, 4013 }, { "multihash-thread-mask", 1, nullptr, 4013 }, @@ -246,6 +248,7 @@ static struct option const cc_client_options[] = { { "update-interval-s", 1, nullptr, 4012 }, { "use-tls", 0, nullptr, 4016 }, { "use-remote-logging", 0, nullptr, 4017 }, + { "upload-config-on-startup", 0, nullptr, 4019 }, { nullptr, 0, nullptr, 0 } }; @@ -320,6 +323,7 @@ Options::Options(int argc, char **argv) : m_daemonized(false), m_ccUseTls(false), m_ccUseRemoteLogging(true), + m_ccUploadConfigOnStartup(true), m_configFile(Platform::defaultConfigName()), m_apiToken(nullptr), m_apiWorkerId(nullptr), @@ -587,6 +591,9 @@ bool Options::parseArg(int key, const char *arg) case 4017: /* --cc-use-remote-logging */ return parseBoolean(key, true); + case 4019: /* --cc-upload-config-on-startup */ + return parseBoolean(key, true); + case 't': /* --threads */ if (strncmp(arg, "all", 3) == 0) { m_threads = Cpu::threads(); @@ -823,6 +830,10 @@ bool Options::parseBoolean(int key, bool enable) m_ccUseRemoteLogging = enable; break; + case 4019: /* --cc-upload-config-on-startup */ + m_ccUploadConfigOnStartup = enable; + break; + default: break; } diff --git a/src/Options.h b/src/Options.h index cc89e887..799980af 100644 --- a/src/Options.h +++ b/src/Options.h @@ -73,6 +73,7 @@ public: inline bool daemonized() const { return m_daemonized; } inline bool ccUseTls() const { return m_ccUseTls; } inline bool ccUseRemoteLogging() const { return m_ccUseRemoteLogging; } + inline bool ccUploadConfigOnStartup() const { return m_ccUploadConfigOnStartup; } inline const char *configFile() const { return m_configFile; } inline const char *apiToken() const { return m_apiToken; } inline const char *apiWorkerId() const { return m_apiWorkerId; } @@ -147,6 +148,7 @@ private: bool m_daemonized; bool m_ccUseTls; bool m_ccUseRemoteLogging; + bool m_ccUploadConfigOnStartup; const char* m_configFile; char *m_apiToken; char *m_apiWorkerId; diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp index 596f2731..beae6d3e 100644 --- a/src/cc/CCClient.cpp +++ b/src/cc/CCClient.cpp @@ -320,7 +320,9 @@ void CCClient::onThreadStarted(void* handle) static_cast(m_self->m_options->ccUpdateInterval() * 1000), static_cast(m_self->m_options->ccUpdateInterval() * 1000)); - m_self->publishConfig(); + if (m_self->m_options->ccUploadConfigOnStartup()) { + m_self->publishConfig(); + } uv_run(&m_self->m_client_loop, UV_RUN_DEFAULT); } diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp index 6c9e317b..03a885ff 100644 --- a/src/cc/Service.cpp +++ b/src/cc/Service.cpp @@ -288,8 +288,6 @@ unsigned Service::getClientLog(const std::string& clientId, std::string& resp) data << m_row.c_str() << std::endl; } - LOG_INFO("LOG: %s", data.str().c_str()); - respDocument.AddMember("client_log", rapidjson::StringRef(data.str().c_str()), allocator); rapidjson::StringBuffer buffer(0, 4096); diff --git a/src/config.json b/src/config.json index 2a8aab50..1b5f397b 100644 --- a/src/config.json +++ b/src/config.json @@ -35,6 +35,7 @@ "worker-id": null, // custom worker-id for CC Server (otherwise hostname is used) "update-interval-s": 10, // status update interval in seconds (default: 10 min: 1) "use-remote-logging" : true, // enable remote logging on CC Server - "remote-logging-max-rows" : 20 // maximum last n-log rows to send CC Server + "remote-logging-max-rows" : 20, // maximum last n-log rows to send CC Server + "upload-config-on-startup" : true // upload current miner config to CC Server on startup } } diff --git a/src/default_config.json b/src/default_config.json index 2a8aab50..a92a4424 100644 --- a/src/default_config.json +++ b/src/default_config.json @@ -5,7 +5,7 @@ "multihash-factor": 0, // number of hash blocks to process at a time (not set or 0 enables automatic selection of optimal number of hash blocks) "multihash-thread-mask" : null, // for multihash-factors>0 only, limits multihash to given threads (mask), mask "0x3" means run multihash on thread 0 and 1 only (default: all threads) "pow-variant" : "auto", // specificy the PoW variat to use: -> auto (default), 0 (v0), 1 (v1, aka monerov7, aeonv7), tube (ipbc), alloy, xtl (including autodetect for v5), msr, xhv, rto - // for further help see: https://github.com/Bendr0id/xmrigCC/wiki/Coin-configurations + // for further help see: https://github.com/Bendr0id/xmrigCC/wiki/Coin-configurations "background": false, // true to run the miner in the background (Windows only, for *nix plase use screen/tmux or systemd service instead) "colors": true, // false to disable colored output "cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1 @@ -35,6 +35,7 @@ "worker-id": null, // custom worker-id for CC Server (otherwise hostname is used) "update-interval-s": 10, // status update interval in seconds (default: 10 min: 1) "use-remote-logging" : true, // enable remote logging on CC Server - "remote-logging-max-rows" : 20 // maximum last n-log rows to send CC Server + "remote-logging-max-rows" : 20, // maximum last n-log rows to send CC Server + "upload-config-on-startup" : true // upload current miner config to CC Server on startup } } diff --git a/src/version.h b/src/version.h index 3bc2011d..3d91f8c3 100644 --- a/src/version.h +++ b/src/version.h @@ -36,14 +36,14 @@ #define APP_DESC "XMRigCC CPU miner" #define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id" #endif -#define APP_VERSION "1.6.5 (based on XMRig)" +#define APP_VERSION "1.6.6_beta1 (based on XMRig)" #define APP_DOMAIN "" #define APP_SITE "https://github.com/Bendr0id/xmrigCC" #define APP_KIND "cpu" #define APP_VER_MAJOR 1 #define APP_VER_MINOR 6 -#define APP_VER_BUILD 5 +#define APP_VER_BUILD 6 #define APP_VER_REV 0 #ifndef NDEBUG From e5f4f3f95d0d36b0e26cff7f0e771c342445dcdc Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Thu, 2 Aug 2018 14:50:23 +0200 Subject: [PATCH 5/9] Cleanup --- README.md | 2 +- src/config.json | 1 - src/default_config.json | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 315e74b7..56aef919 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ xmrigDaemon -o pool.minemonero.pro:5555 -u YOUR_WALLET -p x -k --cc-url=IP_OF_CC --cc-worker-id=ID custom worker-id for CC Server --cc-update-interval-s=N status update interval in seconds (default: 10 min: 1) --cc-use-remote-logging enable remote logging on CC Server - --cc-remote-logging-max-rows=N maximum last n-log rows to send CC Server + --cc-upload-config-on-startup upload current miner config to CC Server on startup --no-color disable colored output -S, --syslog use system log for output messages -B, --background run the miner in the background diff --git a/src/config.json b/src/config.json index 1b5f397b..f777770c 100644 --- a/src/config.json +++ b/src/config.json @@ -35,7 +35,6 @@ "worker-id": null, // custom worker-id for CC Server (otherwise hostname is used) "update-interval-s": 10, // status update interval in seconds (default: 10 min: 1) "use-remote-logging" : true, // enable remote logging on CC Server - "remote-logging-max-rows" : 20, // maximum last n-log rows to send CC Server "upload-config-on-startup" : true // upload current miner config to CC Server on startup } } diff --git a/src/default_config.json b/src/default_config.json index a92a4424..d3081d1b 100644 --- a/src/default_config.json +++ b/src/default_config.json @@ -35,7 +35,6 @@ "worker-id": null, // custom worker-id for CC Server (otherwise hostname is used) "update-interval-s": 10, // status update interval in seconds (default: 10 min: 1) "use-remote-logging" : true, // enable remote logging on CC Server - "remote-logging-max-rows" : 20, // maximum last n-log rows to send CC Server "upload-config-on-startup" : true // upload current miner config to CC Server on startup } } From c91c7cd79830f1a3efcd28509372f6b958fb7cda Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Tue, 14 Aug 2018 15:43:54 +0200 Subject: [PATCH 6/9] WIP GPU integration --- CMakeLists.txt | 3 +- src/Options.cpp | 4 +- src/Options.h | 4 +- src/cc/CCClient.cpp | 143 +++++++++++++++++++---------- src/cc/CCClient.h | 31 +++++-- src/cc/ClientStatus.cpp | 44 ++++++--- src/cc/ClientStatus.h | 17 ++-- src/cc/ControlCommand.cpp | 16 ++-- src/cc/ControlCommand.h | 11 +-- src/cc/GPUInfo.cpp | 187 ++++++++++++++++++++++++++++++++++++++ src/cc/GPUInfo.h | 75 +++++++++++++++ src/cc/README.md | 7 -- 12 files changed, 432 insertions(+), 110 deletions(-) create mode 100644 src/cc/GPUInfo.cpp create mode 100644 src/cc/GPUInfo.h delete mode 100644 src/cc/README.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 4686286a..a2cfccc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,7 +206,8 @@ endif() if (WITH_CC_SERVER OR WITH_CC_CLIENT) set(SOURCES_CC_COMMON src/cc/ControlCommand.cpp - src/cc/ClientStatus.cpp) + src/cc/ClientStatus.cpp + src/cc/GPUInfo.cpp) else() add_definitions(/DXMRIG_NO_CC) endif() diff --git a/src/Options.cpp b/src/Options.cpp index 9b24e6ae..464499a8 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -324,7 +324,7 @@ Options::Options(int argc, char **argv) : m_ccUseTls(false), m_ccUseRemoteLogging(true), m_ccUploadConfigOnStartup(true), - m_configFile(Platform::defaultConfigName()), + m_fileName(Platform::defaultConfigName()), m_apiToken(nullptr), m_apiWorkerId(nullptr), m_logFile(nullptr), @@ -856,7 +856,7 @@ Url *Options::parseUrl(const char *arg) const void Options::parseConfig(const char *fileName) { - m_configFile = fileName; + m_fileName = fileName; rapidjson::Document doc; if (!getJSON(fileName, doc)) { diff --git a/src/Options.h b/src/Options.h index 799980af..39d26ffd 100644 --- a/src/Options.h +++ b/src/Options.h @@ -74,7 +74,7 @@ public: inline bool ccUseTls() const { return m_ccUseTls; } inline bool ccUseRemoteLogging() const { return m_ccUseRemoteLogging; } inline bool ccUploadConfigOnStartup() const { return m_ccUploadConfigOnStartup; } - inline const char *configFile() const { return m_configFile; } + inline const char *fileName() const { return m_fileName; } inline const char *apiToken() const { return m_apiToken; } inline const char *apiWorkerId() const { return m_apiWorkerId; } inline const char *logFile() const { return m_logFile; } @@ -149,7 +149,7 @@ private: bool m_ccUseTls; bool m_ccUseRemoteLogging; bool m_ccUploadConfigOnStartup; - const char* m_configFile; + const char* m_fileName; char *m_apiToken; char *m_apiWorkerId; char *m_logFile; diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp index beae6d3e..6e1fe633 100644 --- a/src/cc/CCClient.cpp +++ b/src/cc/CCClient.cpp @@ -1,10 +1,4 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig +/* XMRigCC * Copyright 2017- BenDr0id * * @@ -28,18 +22,26 @@ #include <3rdparty/rapidjson/stringbuffer.h> #include <3rdparty/rapidjson/prettywriter.h> #include -#include #include #include "CCClient.h" #include "App.h" -#include "Platform.h" #include "Cpu.h" -#include "Mem.h" #include "ControlCommand.h" -#include "api/NetworkState.h" +#ifdef TYPE_AMD_GPU +#include "common/log/Log.h" +#include "common/log/RemoteLog.h" +#include "common/Platform.h" +#include "core/Config.h" +#else +#include "Mem.h" #include "log/Log.h" +#include "log/RemoteLog.h" +#include "Platform.h" +#include "api/NetworkState.h" +#endif + #include "workers/Workers.h" #include "workers/Hashrate.h" @@ -55,8 +57,12 @@ CCClient* CCClient::m_self = nullptr; uv_mutex_t CCClient::m_mutex; -CCClient::CCClient(Options* options, uv_async_t* async) - : m_options(options), +#ifdef TYPE_AMD_GPU +CCClient::CCClient(xmrig::Config* config, uv_async_t* async) +#else +CCClient::CCClient(Options* config, uv_async_t* async) +#endif + : m_config(config), m_async(async) { uv_mutex_init(&m_mutex); @@ -64,8 +70,8 @@ CCClient::CCClient(Options* options, uv_async_t* async) m_self = this; std::string clientId; - if (m_options->ccWorkerId()) { - clientId = m_options->ccWorkerId(); + if (config->ccWorkerId()) { + clientId =m_self->m_config->ccWorkerId(); } else { char hostname[128]; memset(hostname, 0, sizeof(hostname)); @@ -74,27 +80,28 @@ CCClient::CCClient(Options* options, uv_async_t* async) } m_clientStatus.setClientId(clientId); - - if (m_options->algoName() != nullptr) { - m_clientStatus.setCurrentAlgoName(m_options->algoName()); - } - - m_clientStatus.setHashFactor(Mem::hashFactor()); m_clientStatus.setVersion(Version::string()); m_clientStatus.setCpuBrand(Cpu::brand()); m_clientStatus.setCpuAES(Cpu::hasAES()); - m_clientStatus.setCpuSockets(Cpu::sockets()); - m_clientStatus.setCpuCores(Cpu::cores()); - m_clientStatus.setCpuThreads(Cpu::threads()); + m_clientStatus.setCpuSockets(static_cast(Cpu::sockets())); + m_clientStatus.setCpuCores(static_cast(Cpu::cores())); + m_clientStatus.setCpuThreads(static_cast(Cpu::threads())); m_clientStatus.setCpuX64(Cpu::isX64()); - m_clientStatus.setCpuL2(Cpu::l2()); - m_clientStatus.setCpuL3(Cpu::l3()); - m_clientStatus.setCurrentThreads(m_options->threads()); + m_clientStatus.setCpuL2(static_cast(Cpu::l2())); + m_clientStatus.setCpuL3(static_cast(Cpu::l3())); + +#ifdef TYPE_AMD_GPU + m_clientStatus.setCurrentThreads(static_cast(config->threads().size())); + m_clientStatus.setCurrentAlgoName(config->algorithm().name()); +#else + m_clientStatus.setCurrentThreads(static_cast(config->threads())); + m_clientStatus.setCurrentAlgoName(config->algoName()); +#endif m_startTime = std::chrono::system_clock::now(); - if (m_options->ccToken() != nullptr) { - m_authorization = std::string("Bearer ") + m_self->m_options->ccToken(); + if (config->ccToken() != nullptr) { + m_authorization = std::string("Bearer ") + m_self->m_config->ccToken(); } uv_thread_create(&m_thread, CCClient::onThreadStarted, this); @@ -133,16 +140,54 @@ void CCClient::updateNetworkState(const NetworkState& network) m_self->m_clientStatus.setHashesTotal(network.total); m_self->m_clientStatus.setAvgTime(network.avgTime()); +#ifdef TYPE_AMD_GPU + m_clientStatus.setHashFactor(0); + m_self->m_clientStatus.setHugepagesEnabled(false); + m_self->m_clientStatus.setHugepages(false); + m_self->m_clientStatus.setTotalPages(0); + m_self->m_clientStatus.setTotalHugepages(0); + m_self->m_clientStatus.setCurrentPowVariantName(xmrig::Algorithm::getVariantName(network.powVariant)); +#else + m_self->m_clientStatus.setHashFactor(Mem::hashFactor()); m_self->m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled()); m_self->m_clientStatus.setHugepages(Mem::isHugepagesAvailable()); m_self->m_clientStatus.setTotalPages(Mem::getTotalPages()); m_self->m_clientStatus.setTotalHugepages(Mem::getTotalHugepages()); m_self->m_clientStatus.setCurrentPowVariantName(getPowVariantName(network.powVariant)); +#endif uv_mutex_unlock(&m_mutex); } } +#ifdef TYPE_AMD_GPU +void CCClient::updateGpuInfo(const std::vector& gpuContext) +{ + if (m_self) { + uv_mutex_lock(&m_mutex); + + m_self->m_clientStatus.clearGPUInfoList(); + + for (auto gpu : gpuContext) { + GPUInfo gpuInfo; + gpuInfo.setName(gpu.name); + gpuInfo.setCompMode(gpu.compMode); + gpuInfo.setComputeUnits(gpu.computeUnits); + gpuInfo.setDeviceIdx(gpu.deviceIdx); + gpuInfo.setFreeMem(gpu.freeMem); + gpuInfo.setWorkSize(gpu.workSize); + gpuInfo.setMaxWorkSize(gpu.maximumWorkSize); + gpuInfo.setMemChunk(gpu.memChunk); + gpuInfo.setRawIntensity(gpu.rawIntensity); + + m_self->m_clientStatus.addGPUInfo(gpuInfo); + } + + uv_mutex_unlock(&m_mutex); + } +} +#endif + void CCClient::publishClientStatusReport() { std::string requestUrl = "/client/setClientStatus?clientId=" + m_self->m_clientStatus.getClientId(); @@ -151,10 +196,10 @@ void CCClient::publishClientStatusReport() auto res = performRequest(requestUrl, requestBuffer, "POST"); if (!res) { LOG_ERR("[CC-Client] error: unable to performRequest POST -> http://%s:%d%s", - m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str()); + m_self->m_config->ccHost(), m_self->m_config->ccPort(), requestUrl.c_str()); } else if (res->status != 200) { - LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(), - m_self->m_options->ccPort(), requestUrl.c_str()); + LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status,m_self->m_config->ccHost(), + m_self->m_config->ccPort(), requestUrl.c_str()); } else { ControlCommand controlCommand; if (controlCommand.parseFromJsonString(res->body)) { @@ -194,14 +239,14 @@ void CCClient::updateConfig() auto res = performRequest(requestUrl, requestBuffer, "GET"); if (!res) { LOG_ERR("[CC-Client] error: unable to performRequest GET -> http://%s:%d%s", - m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str()); + m_self->m_config->ccHost(), m_self->m_config->ccPort(), requestUrl.c_str()); } else if (res->status != 200) { - LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(), - m_self->m_options->ccPort(), requestUrl.c_str()); + LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_config->ccHost(), + m_self->m_config->ccPort(), requestUrl.c_str()); } else { rapidjson::Document document; if (!document.Parse(res->body.c_str()).HasParseError()) { - std::ofstream clientConfigFile(m_self->m_options->configFile()); + std::ofstream clientConfigFile(m_self->m_config->fileName()); if (clientConfigFile) { rapidjson::StringBuffer buffer(0, 65536); rapidjson::PrettyWriter writer(buffer); @@ -213,7 +258,7 @@ void CCClient::updateConfig() LOG_WARN("[CC-Client] Config updated. -> trigger restart"); } else { - LOG_ERR("[CC-Client] Not able to store client config to file %s.", m_self->m_options->configFile()); + LOG_ERR("[CC-Client] Not able to store client config to file %s.", m_self->m_config->fileName()); } } else { LOG_ERR("[CC-Client] Not able to store client config. received client config is broken!"); @@ -226,7 +271,7 @@ void CCClient::publishConfig() std::string requestUrl = "/client/setClientConfig?clientId=" + m_self->m_clientStatus.getClientId(); std::stringstream data; - std::ifstream clientConfig(m_self->m_options->configFile()); + std::ifstream clientConfig(m_self->m_config->fileName()); if (clientConfig) { data << clientConfig.rdbuf(); @@ -246,16 +291,16 @@ void CCClient::publishConfig() auto res = performRequest(requestUrl, buffer.GetString(), "POST"); if (!res) { LOG_ERR("[CC-Client] error: unable to performRequest POST -> http://%s:%d%s", - m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str()); + m_self->m_config->ccHost(), m_self->m_config->ccPort(), requestUrl.c_str()); } else if (res->status != 200) { - LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(), - m_self->m_options->ccPort(), requestUrl.c_str()); + LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_config->ccHost(), + m_self->m_config->ccPort(), requestUrl.c_str()); } } else { - LOG_ERR("Not able to send config. Client config %s is broken!", m_self->m_options->configFile()); + LOG_ERR("Not able to send config. Client config %s is broken!", m_self->m_config->fileName()); } } else { - LOG_ERR("Not able to load client config %s. Please make sure it exists!", m_self->m_options->configFile()); + LOG_ERR("Not able to load client config %s. Please make sure it exists!", m_self->m_config->fileName()); } } @@ -266,11 +311,11 @@ std::shared_ptr CCClient::performRequest(const std::string& r std::shared_ptr cli; # ifndef XMRIG_NO_TLS - if (m_self->m_options->ccUseTls()) { - cli = std::make_shared(m_self->m_options->ccHost(), m_self->m_options->ccPort(), 10); + if (m_self->m_config->ccUseTls()) { + cli = std::make_shared(m_self->m_config->ccHost(), m_self->m_config->ccPort(), 10); } else { # endif - cli = std::make_shared(m_self->m_options->ccHost(), m_self->m_options->ccPort(), 10); + cli = std::make_shared(m_self->m_config->ccHost(), m_self->m_config->ccPort(), 10); # ifndef XMRIG_NO_TLS } # endif @@ -317,10 +362,10 @@ void CCClient::onThreadStarted(void* handle) uv_timer_init(&m_self->m_client_loop, &m_self->m_timer); uv_timer_start(&m_self->m_timer, CCClient::onReport, - static_cast(m_self->m_options->ccUpdateInterval() * 1000), - static_cast(m_self->m_options->ccUpdateInterval() * 1000)); + static_cast(m_self->m_config->ccUpdateInterval() * 1000), + static_cast(m_self->m_config->ccUpdateInterval() * 1000)); - if (m_self->m_options->ccUploadConfigOnStartup()) { + if (m_self->m_config->ccUploadConfigOnStartup()) { m_self->publishConfig(); } diff --git a/src/cc/CCClient.h b/src/cc/CCClient.h index 0cf2f457..289bdf2e 100644 --- a/src/cc/CCClient.h +++ b/src/cc/CCClient.h @@ -1,10 +1,4 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig +/* XMRigCC * Copyright 2017- BenDr0id * * @@ -31,8 +25,15 @@ #include #include #include <3rdparty/cpp-httplib/httplib.h> -#include "Options.h" #include "ClientStatus.h" +#include "version.h" + +#ifdef TYPE_AMD_GPU +#include "amd/GpuContext.h" +#include "core/Controller.h" +#else +#include "Options.h" +#endif class Hashrate; class NetworkState; @@ -40,7 +41,13 @@ class NetworkState; class CCClient { public: - CCClient(Options *options, uv_async_t* async); +#ifdef TYPE_AMD_GPU + CCClient(xmrig::Config* m_config, uv_async_t* async); + static void updateGpuInfo(const std::vector& network); +#else + CCClient(Options* config, uv_async_t* async); +#endif + ~CCClient(); static void updateHashrate(const Hashrate *hashrate); @@ -60,7 +67,11 @@ private: static void onThreadStarted(void *handle); static void onReport(uv_timer_t *handle); - const Options* m_options; +#ifdef TYPE_AMD_GPU + const xmrig::Config* m_config; +#else + const Options* m_config; +#endif static CCClient* m_self; static uv_mutex_t m_mutex; diff --git a/src/cc/ClientStatus.cpp b/src/cc/ClientStatus.cpp index cddb8c89..42182cc2 100644 --- a/src/cc/ClientStatus.cpp +++ b/src/cc/ClientStatus.cpp @@ -1,13 +1,6 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig +/* XMRigCC * Copyright 2017- BenDr0id * - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -27,7 +20,6 @@ #include #include <3rdparty/rapidjson/stringbuffer.h> #include <3rdparty/rapidjson/prettywriter.h> -#include #include "ClientStatus.h" @@ -491,6 +483,18 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document) m_cpuL3 = clientStatus["cpu_l3"].GetInt(); } + if (clientStatus.HasMember("gpu_info_list") && clientStatus["gpu_info_list"].IsArray()) { + m_gpuInfoList.clear(); + + auto gpuInfoList = clientStatus["gpu_info_list"].GetArray(); + for (rapidjson::Value::ConstValueIterator itr = gpuInfoList.Begin(); itr != gpuInfoList.End(); ++itr) { + GPUInfo gpuInfo; + gpuInfo.parseFromJson((*itr)["gpu_info"]); + + m_gpuInfoList.push_back(gpuInfo); + } + } + if (clientStatus.HasMember("shares_good")) { m_sharesGood = clientStatus["shares_good"].GetUint64(); } @@ -515,8 +519,6 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document) m_lastStatusUpdate = std::chrono::system_clock::to_time_t(time_point); result = true; - } else { - LOG_ERR("Parse Error, JSON does not contain: control_command"); } return result; @@ -556,6 +558,14 @@ rapidjson::Value ClientStatus::toJson(rapidjson::MemoryPoolAllocator(m_lastStatusUpdate), allocator); - clientStatus.AddMember("log", rapidjson::StringRef(m_log.c_str()), allocator); @@ -589,3 +597,13 @@ std::string ClientStatus::toJsonString() return strdup(buffer.GetString()); } + +void ClientStatus::clearGPUInfoList() +{ + m_gpuInfoList.clear(); +} + +void ClientStatus::addGPUInfo(const GPUInfo gpuInfo) +{ + m_gpuInfoList.push_back(gpuInfo); +} diff --git a/src/cc/ClientStatus.h b/src/cc/ClientStatus.h index e8204126..65eb1ed2 100644 --- a/src/cc/ClientStatus.h +++ b/src/cc/ClientStatus.h @@ -1,10 +1,4 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig +/* XMRigCC * Copyright 2017- BenDr0id * * @@ -27,7 +21,9 @@ #include #include +#include #include +#include "GPUInfo.h" class ClientStatus { @@ -136,6 +132,10 @@ public: int getCpuL3() const; void setCpuL3(int cpuL3); + const std::list getGPUInfoList() const; + void addGPUInfo(const GPUInfo gpuInfo); + void clearGPUInfoList(); + uint64_t getSharesGood() const; void setSharesGood(uint64_t sharesGood); @@ -157,7 +157,6 @@ public: rapidjson::Value toJson(rapidjson::MemoryPoolAllocator& allocator); bool parseFromJson(const rapidjson::Document& document); - private: const char* status_str[3] = { "RUNNING", @@ -196,6 +195,8 @@ private: int m_cpuL2; int m_cpuL3; + std::list m_gpuInfoList; + uint64_t m_sharesGood; uint64_t m_sharesTotal; uint64_t m_hashesTotal; diff --git a/src/cc/ControlCommand.cpp b/src/cc/ControlCommand.cpp index a7cd663e..85dfdaf2 100644 --- a/src/cc/ControlCommand.cpp +++ b/src/cc/ControlCommand.cpp @@ -1,13 +1,6 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig +/* XMRigCC * Copyright 2017- BenDr0id * - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -25,7 +18,12 @@ #include <3rdparty/rapidjson/stringbuffer.h> #include <3rdparty/rapidjson/prettywriter.h> +#ifdef TYPE_AMD_GPU +#include "common/log/Log.h" +#else #include "log/Log.h" +#endif + #include "ControlCommand.h" ControlCommand::ControlCommand() @@ -81,7 +79,7 @@ rapidjson::Value ControlCommand::toJson(rapidjson::MemoryPoolAllocator - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig +/* XMRigCC * Copyright 2017- BenDr0id * - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -74,7 +67,7 @@ public: bool parseFromJson(const rapidjson::Document& document); Command getCommand() const; - void setCommand(Command command); + void setCommand(const Command& command); bool isOneTimeCommand() const; diff --git a/src/cc/GPUInfo.cpp b/src/cc/GPUInfo.cpp new file mode 100644 index 00000000..72ba83f9 --- /dev/null +++ b/src/cc/GPUInfo.cpp @@ -0,0 +1,187 @@ +/* XMRigCC + * Copyright 2018- BenDr0id + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "GPUInfo.h" + +GPUInfo::GPUInfo() + : m_deviceIdx(0), + m_rawIntensity(0), + m_workSize(0), + m_maxWorkSize(0), + m_freeMem(0), + m_memChunk(0), + m_compMode(0), + m_computeUnits(0) +{ + +} + +GPUInfo::~GPUInfo() +{ + +} + +rapidjson::Value GPUInfo::toJson(rapidjson::MemoryPoolAllocator & allocator) +{ + rapidjson::Value gpuInfo(rapidjson::kObjectType); + + gpuInfo.AddMember("name", rapidjson::StringRef(m_name.c_str()), allocator); + gpuInfo.AddMember("device_idx", m_deviceIdx, allocator); + gpuInfo.AddMember("raw_intensity", m_rawIntensity, allocator); + gpuInfo.AddMember("work_size", m_workSize, allocator); + gpuInfo.AddMember("max_work_size", m_maxWorkSize, allocator); + gpuInfo.AddMember("free_mem", m_freeMem, allocator); + gpuInfo.AddMember("mem_chunk", m_memChunk, allocator); + gpuInfo.AddMember("comp_mode", m_memChunk, allocator); + gpuInfo.AddMember("compute_units", m_memChunk, allocator); + + return gpuInfo; +} + +bool GPUInfo::parseFromJson(const rapidjson::Value& gpuInfo) +{ + bool result = false; + + if (gpuInfo.HasMember("name")) { + m_name = gpuInfo["name"].GetString(); + result = true; + } + + if (gpuInfo.HasMember("device_idx")) { + m_deviceIdx = static_cast(gpuInfo["device_idx"].GetInt()); + } + + if (gpuInfo.HasMember("raw_intensity")) { + m_rawIntensity = static_cast(gpuInfo["raw_intensity"].GetInt()); + } + + if (gpuInfo.HasMember("work_size")) { + m_workSize = static_cast(gpuInfo["work_size"].GetInt()); + } + + if (gpuInfo.HasMember("max_work_size")) { + m_maxWorkSize = static_cast(gpuInfo["max_work_size"].GetInt()); + } + + if (gpuInfo.HasMember("free_mem")) { + m_freeMem = static_cast(gpuInfo["free_mem"].GetInt()); + } + + if (gpuInfo.HasMember("mem_chunk")) { + m_memChunk = gpuInfo["mem_chunk"].GetInt(); + } + + if (gpuInfo.HasMember("comp_mode")) { + m_compMode = gpuInfo["comp_mode"].GetInt(); + } + + if (gpuInfo.HasMember("compute_units")) { + m_computeUnits = gpuInfo["compute_units"].GetInt(); + } + + return result; +} + +size_t GPUInfo::getDeviceIdx() const +{ + return m_deviceIdx; +} + +void GPUInfo::setDeviceIdx(size_t deviceIdx) +{ + m_deviceIdx = deviceIdx; +} + +size_t GPUInfo::getRawIntensity() const +{ + return m_rawIntensity; +} + +void GPUInfo::setRawIntensity(size_t rawIntensity) +{ + m_rawIntensity = rawIntensity; +} + +size_t GPUInfo::getWorkSize() const +{ + return m_workSize; +} + +void GPUInfo::setWorkSize(size_t workSize) +{ + m_workSize = workSize; +} + +size_t GPUInfo::getMaxWorkSize() const +{ + return m_maxWorkSize; +} + +void GPUInfo::setMaxWorkSize(size_t maxWorkSize) +{ + m_maxWorkSize = maxWorkSize; +} + +size_t GPUInfo::getFreeMem() const +{ + return m_freeMem; +} + +void GPUInfo::setFreeMem(size_t freeMem) +{ + m_freeMem = freeMem; +} + +int GPUInfo::getMemChunk() const +{ + return m_memChunk; +} + +void GPUInfo::setMemChunk(int memChunk) +{ + m_memChunk = memChunk; +} + +int GPUInfo::getCompMode() const +{ + return m_compMode; +} + +void GPUInfo::setCompMode(int compMode) +{ + m_compMode = compMode; +} + +int GPUInfo::getComputeUnits() const +{ + return m_computeUnits; +} + +void GPUInfo::setComputeUnits(int computeUnits) +{ + m_computeUnits = computeUnits; +} + +std::string GPUInfo::getName() const +{ + return m_name; +} + +void GPUInfo::setName(const std::string& name) +{ + m_name = name; +} diff --git a/src/cc/GPUInfo.h b/src/cc/GPUInfo.h new file mode 100644 index 00000000..63194895 --- /dev/null +++ b/src/cc/GPUInfo.h @@ -0,0 +1,75 @@ +/* XMRigCC + * Copyright 2018- BenDr0id + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_GPUINFO_H +#define XMRIG_GPUINFO_H + +#include +#include <3rdparty/rapidjson/document.h> + +class GPUInfo +{ +public: + GPUInfo(); + ~GPUInfo(); + + rapidjson::Value toJson(rapidjson::MemoryPoolAllocator& allocator); + bool parseFromJson(const rapidjson::Value& gpuInfo); + + std::string getName() const; + void setName(const std::string& name); + + size_t getDeviceIdx() const; + void setDeviceIdx(size_t deviceIdx); + + size_t getRawIntensity() const; + void setRawIntensity(size_t rawIntensity); + + size_t getWorkSize() const; + void setWorkSize(size_t workSize); + + size_t getMaxWorkSize() const; + void setMaxWorkSize(size_t maxWorkSize); + + size_t getFreeMem() const; + void setFreeMem(size_t freeMem); + + int getMemChunk() const; + void setMemChunk(int memChunk); + + int getCompMode() const; + void setCompMode(int compMode); + + int getComputeUnits() const; + void setComputeUnits(int computeUnits); + +private: + size_t m_deviceIdx; + size_t m_rawIntensity; + size_t m_workSize; + size_t m_maxWorkSize; + size_t m_freeMem; + + int m_memChunk; + int m_compMode; + int m_computeUnits; + + std::string m_name; +}; + + +#endif //XMRIG_GPUINFO_H diff --git a/src/cc/README.md b/src/cc/README.md deleted file mode 100644 index f414dfa6..00000000 --- a/src/cc/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# XMRigCC common repository -This repository contains all common XMRigCC files. - -# Used in this repos -* [xmrigCC](https://github.com/bendr0id/xmrigCC) -* [xmrigCC-nvidia](https://github.com/bendr0id/xmrigCC-nvidia) - From 72aa8f1cc04a3c0d10075f57f5c097e0d9543ffc Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Tue, 14 Aug 2018 15:57:50 +0200 Subject: [PATCH 7/9] Fixed compile issues for amd --- src/cc/CCClient.cpp | 7 ++++--- src/cc/ControlCommand.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp index 6e1fe633..854ecbf0 100644 --- a/src/cc/CCClient.cpp +++ b/src/cc/CCClient.cpp @@ -21,8 +21,9 @@ #include #include <3rdparty/rapidjson/stringbuffer.h> #include <3rdparty/rapidjson/prettywriter.h> -#include -#include + +#include "version.h" +#include "api/NetworkState.h" #include "CCClient.h" #include "App.h" @@ -141,7 +142,7 @@ void CCClient::updateNetworkState(const NetworkState& network) m_self->m_clientStatus.setAvgTime(network.avgTime()); #ifdef TYPE_AMD_GPU - m_clientStatus.setHashFactor(0); + m_self->m_clientStatus.setHashFactor(0); m_self->m_clientStatus.setHugepagesEnabled(false); m_self->m_clientStatus.setHugepages(false); m_self->m_clientStatus.setTotalPages(0); diff --git a/src/cc/ControlCommand.cpp b/src/cc/ControlCommand.cpp index 85dfdaf2..aeb5c4de 100644 --- a/src/cc/ControlCommand.cpp +++ b/src/cc/ControlCommand.cpp @@ -15,17 +15,20 @@ * along with this program. If not, see . */ +#include #include <3rdparty/rapidjson/stringbuffer.h> #include <3rdparty/rapidjson/prettywriter.h> +#include "ControlCommand.h" + +#include "version.h" + #ifdef TYPE_AMD_GPU #include "common/log/Log.h" #else #include "log/Log.h" #endif -#include "ControlCommand.h" - ControlCommand::ControlCommand() : m_command(Command::START) { From 959be3da385b10dfefff9f533486d2328d65003e Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Wed, 15 Aug 2018 08:44:45 +0200 Subject: [PATCH 8/9] Add GPU Info to client info tooltip --- index.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/index.html b/index.html index 29ebd37d..811567d7 100644 --- a/index.html +++ b/index.html @@ -590,6 +590,18 @@ tooltip += "Used Threads: " + row.client_status.current_threads; tooltip += (row.client_status.hash_factor > 1 ? " [" + row.client_status.hash_factor + "x multi hash mode]" :""); tooltip += '\n'; + + if (row.client_status.gpu_info_list) { + for (var id in row.client_status.gpu_info_list) { + tooltip += "GPU #" + row.client_status.gpu_info_list[id].gpu_info.device_idx + ": "; + tooltip += row.client_status.gpu_info_list[id].gpu_info.name + ", " + tooltip += "intensity: " + row.client_status.gpu_info_list[id].gpu_info.raw_intensity + " "; + tooltip += "("+ row.client_status.gpu_info_list[id].gpu_info.work_size + "/" + row.client_status.gpu_info_list[id].gpu_info.max_work_size + "), "; + tooltip += "cu: " + row.client_status.gpu_info_list[id].gpu_info.compute_units; + tooltip += '\n'; + } + } + tooltip += "Client IP: " + row.client_status.external_ip; tooltip += '\n'; tooltip += "Version: " + row.client_status.version; From f49296f394468e1e959a164e4c7d5e6dfcaf1b97 Mon Sep 17 00:00:00 2001 From: BenDr0id Date: Thu, 16 Aug 2018 09:00:58 +0200 Subject: [PATCH 9/9] XMRigDaemon and XMRigMiner executable can be configures via -D cmake option now --- CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2cfccc0..605bb52f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,12 +11,17 @@ option(WITH_CC_CLIENT "CC Client" ON) option(WITH_CC_SERVER "CC Server" ON) option(WITH_TLS "TLS support" ON) option(BUILD_STATIC "Build static binary" OFF) -set(MINER_EXECUTABLE_NAME "xmrigMiner" CACHE STRING "Miner executable file name") -set(DAEMON_EXECUTABLE_NAME "xmrigDaemon" CACHE STRING "Daemon executable file name") - set(Boost_USE_STATIC_RUNTIME ON) set(Boost_USE_STATIC_LIBS ON) +if(NOT MINER_EXECUTABLE_NAME) +set(MINER_EXECUTABLE_NAME "xmrigMiner" CACHE STRING "Miner executable file name") +endif(MINER_EXECUTABLE_NAME) + +if(NOT DAEMON_EXECUTABLE_NAME) +set(DAEMON_EXECUTABLE_NAME "xmrigDaemon" CACHE STRING "Daemon executable file name") +endif(DAEMON_EXECUTABLE_NAME) + include (CheckIncludeFile) include (cmake/cpu.cmake)