WIP
This commit is contained in:
parent
527b557f9e
commit
ed80e8a436
12 changed files with 117 additions and 50 deletions
37
index.html
37
index.html
|
@ -411,15 +411,24 @@
|
||||||
var data = table.row( $(this).parents('tr') ).data();
|
var data = table.row( $(this).parents('tr') ).data();
|
||||||
var clientId = data['client_status']['client_id'];
|
var clientId = data['client_status']['client_id'];
|
||||||
var clientIp = data['client_status']['external_ip'];
|
var clientIp = data['client_status']['external_ip'];
|
||||||
var log = data['client_status']['log'];
|
|
||||||
|
|
||||||
var htmlContent = "<div class='form-group' id='viewer' data-value='" + clientId + "'>" +
|
$.ajax({
|
||||||
"<label for='config'>Log of: " + clientId + " (" + clientIp + ")</label>"+
|
type: "GET",
|
||||||
"<textarea class='form-control' rows='20' id='log'>" + log + "</textarea>" +
|
url: "/admin/getClientLog?clientId=" + clientId,
|
||||||
"</div>";
|
dataType:"json",
|
||||||
|
success: function(jsonClientLog) {
|
||||||
|
var htmlContent = "<div class='form-group' id='viewer' data-value='" + clientId + "'>" +
|
||||||
|
"<label for='config'>Log of: " + clientId + " (" + clientIp + ")</label>"+
|
||||||
|
"<textarea class='form-control' rows='20' id='log'>" + JSON.stringify(jsonClientLog,undefined, 2) + "</textarea>" +
|
||||||
|
"</div>";
|
||||||
|
|
||||||
$('#minerLog').find('.modal-body').html(htmlContent);
|
$('#minerLog').find('.modal-body').html(htmlContent);
|
||||||
$('#minerLog').modal('show');
|
$('#minerLog').modal('show');
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
setError('<strong>Unable to fetch ' + clientId + ' log.</strong> - Please make sure it is enabled on the miner!');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#minerLogRefresh').click(function(event) {
|
$('#minerLogRefresh').click(function(event) {
|
||||||
|
@ -429,9 +438,17 @@
|
||||||
var row = table.row(index);
|
var row = table.row(index);
|
||||||
var data = row.data();
|
var data = row.data();
|
||||||
|
|
||||||
if (clientId === data.client_status.client_id) {
|
$.ajax({
|
||||||
$('#log').val(data.client_status.log);
|
type: "GET",
|
||||||
}
|
url: "/admin/getClientLog?clientId=" + clientId,
|
||||||
|
dataType:"json",
|
||||||
|
success: function(jsonClientLog) {
|
||||||
|
$('#log').val(JSON.stringify(jsonClientLog,undefined, 2));
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
setError('<strong>Unable to fetch ' + clientId + ' log.</strong> - Please make sure it is enabled on the miner!');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,8 @@ App::App(int argc, char **argv) :
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_options->ccUseRemoteLogging()) {
|
if (m_options->ccUseRemoteLogging()) {
|
||||||
Log::add(new RemoteLog());
|
// 20 lines per second should be enough
|
||||||
|
Log::add(new RemoteLog(static_cast<size_t>(m_options->ccUpdateInterval() * 20)));
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef HAVE_SYSLOG_H
|
# ifdef HAVE_SYSLOG_H
|
||||||
|
|
|
@ -110,6 +110,7 @@ Options:\n"
|
||||||
--cc-use-tls enable tls encryption for CC communication\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-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\
|
--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-client-config-folder=FOLDER Folder contains the client config files\n\
|
||||||
--cc-custom-dashboard=FILE loads a custom dashboard and serve it to '/'\n"
|
--cc-custom-dashboard=FILE loads a custom dashboard and serve it to '/'\n"
|
||||||
# endif
|
# endif
|
||||||
|
@ -182,6 +183,7 @@ static struct option const options[] = {
|
||||||
{ "cc-key-file", 1, nullptr, 4015 },
|
{ "cc-key-file", 1, nullptr, 4015 },
|
||||||
{ "cc-use-tls", 0, nullptr, 4016 },
|
{ "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 },
|
||||||
{ "daemonized", 0, nullptr, 4011 },
|
{ "daemonized", 0, nullptr, 4011 },
|
||||||
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
{ "doublehash-thread-mask", 1, nullptr, 4013 },
|
||||||
{ "multihash-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 },
|
{ "cert-file", 1, nullptr, 4014 },
|
||||||
{ "key-file", 1, nullptr, 4015 },
|
{ "key-file", 1, nullptr, 4015 },
|
||||||
{ "use-tls", 0, nullptr, 4016 },
|
{ "use-tls", 0, nullptr, 4016 },
|
||||||
|
{ "client-log-lines-history", 1, nullptr, 4018 },
|
||||||
{ nullptr, 0, nullptr, 0 }
|
{ nullptr, 0, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -346,6 +349,7 @@ Options::Options(int argc, char **argv) :
|
||||||
m_threads(0),
|
m_threads(0),
|
||||||
m_ccUpdateInterval(10),
|
m_ccUpdateInterval(10),
|
||||||
m_ccPort(0),
|
m_ccPort(0),
|
||||||
|
m_ccClientLogLinesHistory(100),
|
||||||
m_affinity(-1L),
|
m_affinity(-1L),
|
||||||
m_multiHashThreadMask(-1L)
|
m_multiHashThreadMask(-1L)
|
||||||
{
|
{
|
||||||
|
@ -558,6 +562,8 @@ bool Options::parseArg(int key, const char *arg)
|
||||||
case 4006: /* --cc-port */
|
case 4006: /* --cc-port */
|
||||||
case 4012: /* --cc-update-interval-c */
|
case 4012: /* --cc-update-interval-c */
|
||||||
return parseArg(key, strtol(arg, nullptr, 10));
|
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 'B': /* --background */
|
||||||
case 'k': /* --keepalive */
|
case 'k': /* --keepalive */
|
||||||
|
@ -756,6 +762,10 @@ bool Options::parseArg(int key, uint64_t arg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 4018: /* --cc-client-log-lines-history */
|
||||||
|
m_ccClientLogLinesHistory = (int) arg;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ public:
|
||||||
inline size_t threads() const { return m_threads; }
|
inline size_t threads() const { return m_threads; }
|
||||||
inline int ccUpdateInterval() const { return m_ccUpdateInterval; }
|
inline int ccUpdateInterval() const { return m_ccUpdateInterval; }
|
||||||
inline int ccPort() const { return m_ccPort; }
|
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 affinity() const { return m_affinity; }
|
||||||
inline int64_t multiHashThreadMask() const { return m_multiHashThreadMask; }
|
inline int64_t multiHashThreadMask() const { return m_multiHashThreadMask; }
|
||||||
inline void setColors(bool colors) { m_colors = colors; }
|
inline void setColors(bool colors) { m_colors = colors; }
|
||||||
|
@ -175,6 +176,7 @@ private:
|
||||||
size_t m_threads;
|
size_t m_threads;
|
||||||
int m_ccUpdateInterval;
|
int m_ccUpdateInterval;
|
||||||
int m_ccPort;
|
int m_ccPort;
|
||||||
|
size_t m_ccClientLogLinesHistory;
|
||||||
int64_t m_affinity;
|
int64_t m_affinity;
|
||||||
int64_t m_multiHashThreadMask;
|
int64_t m_multiHashThreadMask;
|
||||||
std::vector<Url*> m_pools;
|
std::vector<Url*> m_pools;
|
||||||
|
|
|
@ -150,6 +150,11 @@ void ClientStatus::setLog(const std::string& log)
|
||||||
m_log = log;
|
m_log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientStatus::clearLog()
|
||||||
|
{
|
||||||
|
m_log.clear();
|
||||||
|
}
|
||||||
|
|
||||||
bool ClientStatus::hasHugepages() const
|
bool ClientStatus::hasHugepages() const
|
||||||
{
|
{
|
||||||
return m_hasHugepages;
|
return m_hasHugepages;
|
||||||
|
|
|
@ -82,7 +82,8 @@ public:
|
||||||
void setVersion(const std::string& version);
|
void setVersion(const std::string& version);
|
||||||
|
|
||||||
std::string getLog() const;
|
std::string getLog() const;
|
||||||
void setLog(const std::string& version);
|
void setLog(const std::string& log);
|
||||||
|
void clearLog();
|
||||||
|
|
||||||
bool hasHugepages() const;
|
bool hasHugepages() const;
|
||||||
void setHugepages(bool hasHugepages);
|
void setHugepages(bool hasHugepages);
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
uv_mutex_t Service::m_mutex;
|
uv_mutex_t Service::m_mutex;
|
||||||
std::map<std::string, ControlCommand> Service::m_clientCommand;
|
std::map<std::string, ControlCommand> Service::m_clientCommand;
|
||||||
std::map<std::string, ClientStatus> Service::m_clientStatus;
|
std::map<std::string, ClientStatus> Service::m_clientStatus;
|
||||||
std::map<std::string, std::list<std::string>> Service::m_remoteLog;
|
std::map<std::string, std::list<std::string>> Service::m_clientLog;
|
||||||
|
|
||||||
int Service::m_currentServerTime = 0;
|
int Service::m_currentServerTime = 0;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ void Service::release()
|
||||||
|
|
||||||
m_clientCommand.clear();
|
m_clientCommand.clear();
|
||||||
m_clientStatus.clear();
|
m_clientStatus.clear();
|
||||||
m_remoteLog.clear();
|
m_clientLog.clear();
|
||||||
|
|
||||||
uv_mutex_unlock(&m_mutex);
|
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) {
|
} else if (url.rfind("/admin/getClientCommand", 0) == 0) {
|
||||||
resultCode = getClientCommand(clientId, resp);
|
resultCode = getClientCommand(clientId, resp);
|
||||||
} else if (url.rfind("/admin/getClientLog", 0) == 0) {
|
} else if (url.rfind("/admin/getClientLog", 0) == 0) {
|
||||||
//resultCode = getClientCommand(clientId, resp);
|
resultCode = getClientLog(clientId, resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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());
|
url.c_str(), clientIp.c_str(), clientId.c_str(), data.length());
|
||||||
|
|
||||||
if (url.rfind("/client/setClientStatus", 0) == 0) {
|
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) {
|
} else if (url.rfind("/admin/setClientConfig", 0) == 0 || url.rfind("/client/setClientConfig", 0) == 0) {
|
||||||
resultCode = setClientConfig(options, clientId, data, resp);
|
resultCode = setClientConfig(options, clientId, data, resp);
|
||||||
} else if (url.rfind("/admin/setClientCommand", 0) == 0) {
|
} else if (url.rfind("/admin/setClientCommand", 0) == 0) {
|
||||||
|
@ -221,7 +221,7 @@ unsigned Service::getClientStatusList(std::string& resp)
|
||||||
return MHD_HTTP_OK;
|
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;
|
int resultCode = MHD_HTTP_BAD_REQUEST;
|
||||||
|
|
||||||
|
@ -233,6 +233,10 @@ unsigned Service::setClientStatus(const std::string& clientIp, const std::string
|
||||||
clientStatus.parseFromJson(document);
|
clientStatus.parseFromJson(document);
|
||||||
clientStatus.setExternalIp(clientIp);
|
clientStatus.setExternalIp(clientIp);
|
||||||
|
|
||||||
|
setClientLog(options->ccClientLogLinesHistory(), clientId, clientStatus.getLog());
|
||||||
|
|
||||||
|
clientStatus.clearLog();
|
||||||
|
|
||||||
m_clientStatus[clientId] = clientStatus;
|
m_clientStatus[clientId] = clientStatus;
|
||||||
|
|
||||||
resultCode = getClientCommand(clientId, resp);
|
resultCode = getClientCommand(clientId, resp);
|
||||||
|
@ -271,40 +275,22 @@ unsigned Service::getClientCommand(const std::string& clientId, std::string& res
|
||||||
return MHD_HTTP_OK;
|
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)
|
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;
|
rapidjson::Document respDocument;
|
||||||
respDocument.SetObject();
|
respDocument.SetObject();
|
||||||
|
|
||||||
auto& allocator = respDocument.GetAllocator();
|
auto& allocator = respDocument.GetAllocator();
|
||||||
|
|
||||||
rapidjson::Value controlCommand = m_clientCommand[clientId].toJson(allocator);
|
std::stringstream data;
|
||||||
respDocument.AddMember("client_log", controlCommand, allocator);
|
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::StringBuffer buffer(0, 4096);
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||||
|
@ -351,6 +337,49 @@ unsigned Service::getAdminPage(const Options* options, std::string& resp)
|
||||||
return MHD_HTTP_OK;
|
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<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Service::getClientConfigFileName(const Options* options, const std::string& clientId)
|
||||||
{
|
{
|
||||||
std::string clientConfigFileName;
|
std::string clientConfigFileName;
|
||||||
|
|
|
@ -52,11 +52,13 @@ private:
|
||||||
static unsigned getClientStatusList(std::string& resp);
|
static unsigned getClientStatusList(std::string& resp);
|
||||||
static unsigned getAdminPage(const Options* options, 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 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 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 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);
|
static std::string getClientConfigFileName(const Options *options, const std::string &clientId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -64,7 +66,7 @@ private:
|
||||||
|
|
||||||
static std::map<std::string, ClientStatus> m_clientStatus;
|
static std::map<std::string, ClientStatus> m_clientStatus;
|
||||||
static std::map<std::string, ControlCommand> m_clientCommand;
|
static std::map<std::string, ControlCommand> m_clientCommand;
|
||||||
static std::map<std::string, std::list<std::string>> m_remoteLog;
|
static std::map<std::string, std::list<std::string>> m_clientLog;
|
||||||
|
|
||||||
static uv_mutex_t m_mutex;
|
static uv_mutex_t m_mutex;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"user": "admin", // admin user for access CC Dashboard
|
"user": "admin", // admin user for access CC Dashboard
|
||||||
"pass": "pass", // admin pass 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-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
|
"custom-dashboard" : "index.html" // dashboard html file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
Log *Log::m_self = nullptr;
|
Log *Log::m_self = nullptr;
|
||||||
|
|
||||||
|
|
||||||
Log::Log()
|
Log::Log()
|
||||||
{
|
{
|
||||||
uv_mutex_init(&m_mutex);
|
uv_mutex_init(&m_mutex);
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
|
|
||||||
RemoteLog* RemoteLog::m_self = nullptr;
|
RemoteLog* RemoteLog::m_self = nullptr;
|
||||||
|
|
||||||
RemoteLog::RemoteLog()
|
RemoteLog::RemoteLog(size_t maxRows)
|
||||||
: m_maxRows(100)
|
: m_maxRows(maxRows)
|
||||||
{
|
{
|
||||||
uv_mutex_init(&m_mutex);
|
uv_mutex_init(&m_mutex);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
class RemoteLog : public ILogBackend
|
class RemoteLog : public ILogBackend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RemoteLog();
|
RemoteLog(size_t maxRows);
|
||||||
~RemoteLog();
|
~RemoteLog();
|
||||||
|
|
||||||
void message(int level, const char* fmt, va_list args) override;
|
void message(int level, const char* fmt, va_list args) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue