diff --git a/src/Log.cpp b/src/Log.cpp index 74904c6a3..c2314dd77 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -4,6 +4,7 @@ #include #include +#include boost::recursive_mutex Log::sLock; @@ -15,6 +16,28 @@ uint32 Log::logRotateCounter = 0; LogPartition* LogPartition::headLog = NULL; +LogPartition::LogPartition(const char *name) : mNextLog(headLog), mMinSeverity(lsWARNING) +{ + const char *ptr = strrchr(name, '/'); + mName = (ptr == NULL) ? name : (ptr + 1); + + size_t p = mName.find(".cpp"); + if (p != std::string::npos) + mName.erase(mName.begin() + p, mName.end()); + + headLog = this; +} + +std::vector< std::pair > LogPartition::getSeverities() +{ + std::vector< std::pair > sevs; + + for (LogPartition *l = headLog; l != NULL; l = l->mNextLog) + sevs.push_back(std::make_pair(l->mName, Log::severityToString(l->mMinSeverity))); + + return sevs; +} + Log::~Log() { std::string logMsg = boost::posix_time::to_simple_string(boost::posix_time::second_clock::universal_time()); @@ -26,6 +49,7 @@ Log::~Log() case lsWARNING: logMsg += " WARN "; break; case lsERROR: logMsg += " EROR "; break; case lsFATAL: logMsg += " FATL "; break; + case lsINVALID: assert(false); return; } logMsg += oss.str(); boost::recursive_mutex::scoped_lock sl(sLock); @@ -84,6 +108,44 @@ void Log::setMinSeverity(LogSeverity s) LogPartition::setSeverity(s); } +LogSeverity Log::getMinSeverity() +{ + boost::recursive_mutex::scoped_lock sl(sLock); + return sMinSeverity; +} + +std::string Log::severityToString(LogSeverity s) +{ + switch (s) + { + case lsTRACE: return "Trace"; + case lsDEBUG: return "Debug"; + case lsINFO: return "Info"; + case lsWARNING: return "Warning"; + case lsERROR: return "Error"; + case lsFATAL: return "Fatal"; + default: assert(false); return "Unknown"; + } + +} + +LogSeverity Log::stringToSeverity(const std::string& s) +{ + if (boost::iequals(s, "trace")) + return lsTRACE; + if (boost::iequals(s, "debug")) + return lsDEBUG; + if (boost::iequals(s, "info") || boost::iequals(s, "information")) + return lsINFO; + if (boost::iequals(s, "warn") || boost::iequals(s, "warning") || boost::iequals(s, "warnings")) + return lsWARNING; + if (boost::iequals(s, "error") || boost::iequals(s, "errors")) + return lsERROR; + if (boost::iequals(s, "fatal") || boost::iequals(s, "fatals")) + return lsFATAL; + return lsINVALID; +} + void Log::setLogFile(boost::filesystem::path path) { std::ofstream* newStream = new std::ofstream(path.c_str(), std::fstream::app); @@ -103,14 +165,15 @@ void Log::setLogFile(boost::filesystem::path path) pathToLog = new boost::filesystem::path(path); } -void LogPartition::setSeverity(const char *partition, LogSeverity severity) +bool LogPartition::setSeverity(const std::string& partition, LogSeverity severity) { for (LogPartition *p = headLog; p != NULL; p = p->mNextLog) - if (p->mName == partition) + if (boost::iequals(p->mName, partition)) { p->mMinSeverity = severity; - return; + return true; } + return false; } void LogPartition::setSeverity(LogSeverity severity) diff --git a/src/Log.h b/src/Log.h index 10c18fd0e..a0521f909 100644 --- a/src/Log.h +++ b/src/Log.h @@ -28,6 +28,7 @@ enum LogSeverity { + lsINVALID = -1, // used to indicate an invalid severity lsTRACE = 0, // Very low-level progress information, details inside an operation lsDEBUG = 1, // Function-level progress information, operations lsINFO = 2, // Server-level progress information, major operations @@ -46,20 +47,16 @@ protected: std::string mName; public: - LogPartition(const char *name) : mNextLog(headLog), mMinSeverity(lsWARNING) - { - const char *ptr = strrchr(name, '/'); - mName = (ptr == NULL) ? name : ptr; - headLog = this; - } + LogPartition(const char *name); - bool doLog(enum LogSeverity s) + bool doLog(LogSeverity s) { return s >= mMinSeverity; } - static void setSeverity(const char *partition, LogSeverity severity); + static bool setSeverity(const std::string& partition, LogSeverity severity); static void setSeverity(LogSeverity severity); + static std::vector< std::pair > getSeverities(); }; class Log @@ -95,6 +92,10 @@ public: return oss; } + static std::string severityToString(LogSeverity); + static LogSeverity stringToSeverity(const std::string&); + + static LogSeverity getMinSeverity(); static void setMinSeverity(LogSeverity); static void setLogFile(boost::filesystem::path); static std::string rotateLog(void); diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 07d8376cb..7e5c58783 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -1875,8 +1875,8 @@ Json::Value RPCServer::doSend(const Json::Value& params) if (asDst) { // Destination exists, ordinary send. - STPathSet spsPaths; - uint160 srcCurrencyID; + STPathSet spsPaths; + uint160 srcCurrencyID; if (!saSrcAmountMax.isNative() || !saDstAmount.isNative()) { @@ -2610,6 +2610,49 @@ Json::Value RPCServer::doLogin(const Json::Value& params) } } +Json::Value RPCServer::doLogSeverity(const Json::Value& params) +{ + if (params.size() == 0) + { // get log severities + Json::Value ret = Json::objectValue; + + ret["base"] = Log::severityToString(Log::getMinSeverity()); + + std::vector< std::pair > logTable = LogPartition::getSeverities(); + for (std::vector< std::pair >::iterator it = logTable.begin(); + it != logTable.end(); ++it) + ret[it->first] = it->second; + return ret; + } + + if (params.size() == 1) + { // set base log severity + LogSeverity sv = Log::stringToSeverity(params[0u].asString()); + if (sv == lsINVALID) + { + Log(lsWARNING) << "Unable to parse severity: " << params[0u].asString(); + return RPCError(rpcINVALID_PARAMS); + } + Log::setMinSeverity(sv); + return RPCError(rpcSUCCESS); + } + + if (params.size() == 2) + { // set partition severity + LogSeverity sv = Log::stringToSeverity(params[1u].asString()); + if (sv == lsINVALID) + return RPCError(rpcINVALID_PARAMS); + if (params[2u].asString() == "base") + Log::setMinSeverity(sv); + else if (!LogPartition::setSeverity(params[0u].asString(), sv)) + return RPCError(rpcINVALID_PARAMS); + return RPCError(rpcSUCCESS); + } + + assert(false); + return RPCError(rpcINVALID_PARAMS); +} + Json::Value RPCServer::doLogRotate(const Json::Value& params) { return Log::rotateLog(); @@ -2641,7 +2684,8 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params { "data_fetch", &RPCServer::doDataFetch, 1, 1, true }, { "data_store", &RPCServer::doDataStore, 2, 2, true }, { "ledger", &RPCServer::doLedger, 0, 2, false, optNetwork }, - { "logrotate", &RPCServer::doLogRotate, 0, 0, true }, + { "logrotate", &RPCServer::doLogRotate, 0, 0, true }, + { "logseverity", &RPCServer::doLogSeverity, 0, 2, true }, { "nickname_info", &RPCServer::doNicknameInfo, 1, 1, false, optCurrent }, { "nickname_set", &RPCServer::doNicknameSet, 2, 3, false, optCurrent }, { "offer_create", &RPCServer::doOfferCreate, 9, 10, false, optCurrent }, diff --git a/src/RPCServer.h b/src/RPCServer.h index ce859c843..8997707d1 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -160,6 +160,7 @@ private: Json::Value doServerInfo(const Json::Value& params); Json::Value doSessionClose(const Json::Value& params); Json::Value doSessionOpen(const Json::Value& params); + Json::Value doLogSeverity(const Json::Value& params); Json::Value doStop(const Json::Value& params); Json::Value doTransitSet(const Json::Value& params); Json::Value doTx(const Json::Value& params);