Split Log singleton code out into LogInstance

This commit is contained in:
Vinnie Falco
2013-09-11 22:42:40 -07:00
parent 0079c9070d
commit a76672c5f0
5 changed files with 171 additions and 143 deletions

View File

@@ -480,9 +480,9 @@ public:
if (!getConfig ().DEBUG_LOGFILE.empty ())
{
// Let debug messages go to the file but only WARNING or higher to regular output (unless verbose)
Log::setLogFile (getConfig ().DEBUG_LOGFILE);
LogInstance::getInstance()->setLogFile (getConfig ().DEBUG_LOGFILE);
if (Log::getMinSeverity () > lsDEBUG)
if (LogInstance::getInstance()->getMinSeverity () > lsDEBUG)
LogPartition::setSeverity (lsDEBUG);
}

View File

@@ -361,15 +361,15 @@ int RippleMain::run (int argc, char const* const* argv)
if (vm.count ("quiet"))
{
Log::setMinSeverity (lsFATAL, true);
LogInstance::getInstance()->setMinSeverity (lsFATAL, true);
}
else if (vm.count ("verbose"))
{
Log::setMinSeverity (lsTRACE, true);
LogInstance::getInstance()->setMinSeverity (lsTRACE, true);
}
else
{
Log::setMinSeverity (lsINFO, true);
LogInstance::getInstance()->setMinSeverity (lsINFO, true);
}
// Run the unit tests if requested.

View File

@@ -826,7 +826,7 @@ Json::Value RPCHandler::doProfile (Json::Value params, LoadType* loadType, Appli
if (iArgs >= 8 && "false" != params[7u].asString())
bSubmit = true;
Log::setMinSeverity(lsFATAL,true);
LogInstance::getInstance()->setMinSeverity(lsFATAL,true);
boost::posix_time::ptime ptStart(boost::posix_time::microsec_clock::local_time());
@@ -2387,7 +2387,7 @@ Json::Value RPCHandler::doWalletAccounts (Json::Value params, LoadType* loadType
Json::Value RPCHandler::doLogRotate (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
{
return Log::rotateLog ();
return LogInstance::getInstance()->rotateLog ();
}
// {
@@ -2592,7 +2592,7 @@ Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, Appl
Json::Value ret (Json::objectValue);
Json::Value lev (Json::objectValue);
lev["base"] = Log::severityToString (Log::getMinSeverity ());
lev["base"] = Log::severityToString (LogInstance::getInstance()->getMinSeverity ());
std::vector< std::pair<std::string, std::string> > logTable = LogPartition::getSeverities ();
typedef std::map<std::string, std::string>::value_type stringPair;
BOOST_FOREACH (const stringPair & it, logTable)
@@ -2611,7 +2611,7 @@ Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, Appl
if (!params.isMember ("partition"))
{
// set base log severity
Log::setMinSeverity (sv, true);
LogInstance::getInstance()->setMinSeverity (sv, true);
return Json::objectValue;
}
@@ -2622,7 +2622,7 @@ Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, Appl
std::string partition (params["partition"].asString ());
if (boost::iequals (partition, "base"))
Log::setMinSeverity (sv, false);
LogInstance::getInstance()->setMinSeverity (sv, false);
else if (!LogPartition::setSeverity (partition, sv))
return rpcError (rpcINVALID_PARAMS);

View File

@@ -4,12 +4,6 @@
*/
//==============================================================================
LogFile Log::s_logFile;
Log::StaticLockType Log::s_lock ("Log", __FILE__, __LINE__);
LogSeverity Log::sMinSeverity = lsINFO;
//------------------------------------------------------------------------------
LogPartition* LogPartition::headLog = NULL;
LogPartition::LogPartition (char const* partitionName)
@@ -116,73 +110,7 @@ Log::~Log ()
logMsg += "...";
}
print (logMsg, mSeverity >= sMinSeverity);
}
void Log::print (std::string const& text, bool toStdErr)
{
StaticScopedLockType sl (s_lock, __FILE__, __LINE__);
// Does nothing if not open.
s_logFile.writeln (text);
if (toStdErr)
{
#if 0 //BEAST_MSVC
if (beast_isRunningUnderDebugger ())
{
// Send it to the attached debugger's Output window
//
Logger::outputDebugString (text);
}
else
#endif
{
std::cerr << text << std::endl;
}
}
}
void Log::print (StringArray const& strings, bool toStdErr)
{
StaticScopedLockType sl (s_lock, __FILE__, __LINE__);
for (int i = 0; i < strings.size (); ++i)
print (strings [i].toStdString (), toStdErr);
}
std::string Log::rotateLog ()
{
StaticScopedLockType sl (s_lock, __FILE__, __LINE__);
bool const wasOpened = s_logFile.closeAndReopen ();
if (wasOpened)
{
return "The log file was closed and reopened.";
}
else
{
return "The log file could not be closed and reopened.";
}
}
void Log::setMinSeverity (LogSeverity s, bool all)
{
StaticScopedLockType sl (s_lock, __FILE__, __LINE__);
sMinSeverity = s;
if (all)
LogPartition::setSeverity (s);
}
LogSeverity Log::getMinSeverity ()
{
StaticScopedLockType sl (s_lock, __FILE__, __LINE__);
return sMinSeverity;
LogInstance::getInstance()->print (logMsg, mSeverity >= LogInstance::getInstance()->getMinSeverity ());
}
std::string Log::severityToString (LogSeverity s)
@@ -236,16 +164,6 @@ LogSeverity Log::stringToSeverity (const std::string& s)
return lsINVALID;
}
void Log::setLogFile (boost::filesystem::path const& path)
{
bool const wasOpened = s_logFile.open (path.c_str ());
if (! wasOpened)
{
Log (lsFATAL) << "Unable to open logfile " << path;
}
}
bool LogPartition::setSeverity (const std::string& partition, LogSeverity severity)
{
for (LogPartition* p = headLog; p != NULL; p = p->mNextLog)
@@ -264,4 +182,102 @@ void LogPartition::setSeverity (LogSeverity severity)
p->mMinSeverity = severity;
}
// vim:ts=4
//------------------------------------------------------------------------------
LogInstance::LogInstance ()
: SharedSingleton <LogInstance> (SingletonLifetime::persistAfterCreation)
, m_mutex ("Log", __FILE__, __LINE__)
, m_minSeverity (lsINFO)
{
}
LogInstance::~LogInstance ()
{
}
LogInstance* LogInstance::createInstance ()
{
return new LogInstance;
}
LogSeverity LogInstance::getMinSeverity ()
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
return m_minSeverity;
}
void LogInstance::setMinSeverity (LogSeverity s, bool all)
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
m_minSeverity = s;
if (all)
LogPartition::setSeverity (s);
}
void LogInstance::setLogFile (boost::filesystem::path const& path)
{
bool const wasOpened = m_logFile.open (path.c_str ());
if (! wasOpened)
{
Log (lsFATAL) << "Unable to open logfile " << path;
}
}
std::string LogInstance::rotateLog ()
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
bool const wasOpened = m_logFile.closeAndReopen ();
if (wasOpened)
{
return "The log file was closed and reopened.";
}
else
{
return "The log file could not be closed and reopened.";
}
}
void LogInstance::print (std::string const& text, bool toStdErr)
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
write (text, toStdErr);
}
void LogInstance::print (StringArray const& strings, bool toStdErr)
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
for (int i = 0; i < strings.size (); ++i)
write (strings [i].toStdString (), toStdErr);
}
void LogInstance::write (std::string const& line, bool toStdErr)
{
// Does nothing if not open.
m_logFile.writeln (line);
if (toStdErr)
{
#if 0 //BEAST_MSVC
if (beast_isRunningUnderDebugger ())
{
// Send it to the attached debugger's Output window
//
Logger::outputDebugString (line);
}
else
#endif
{
std::cerr << line << std::endl;
}
}
}

View File

@@ -79,6 +79,65 @@ private:
//------------------------------------------------------------------------------
// A singleton which performs the actual logging.
//
class LogInstance : public SharedSingleton <LogInstance>
{
public:
LogInstance ();
~LogInstance ();
static LogInstance* createInstance ();
LogSeverity getMinSeverity ();
void setMinSeverity (LogSeverity, bool all);
void setLogFile (boost::filesystem::path const& pathToLogFile);
/** Rotate the log file.
The log file is closed and reopened. This is for compatibility
with log management tools.
@return A human readable string describing the result of the operation.
*/
std::string rotateLog ();
/** Write to log output.
All logging eventually goes through this function. If a
debugger is attached, the string goes to the debugging console,
else it goes to the standard error output. If a log file is
open, then the message is additionally written to the open log
file.
The text should not contain a newline, it will be automatically
added as needed.
@note This acquires a global mutex.
@param text The text to write.
@param toStdErr `true` to also write to std::cerr
*/
void print (std::string const& text, bool toStdErr = true);
void print (StringArray const& strings, bool toStdErr = true);
private:
void write (std::string const& line, bool toStdErr);
typedef RippleRecursiveMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
LockType m_mutex;
LogFile m_logFile;
LogSeverity m_minSeverity;
};
//------------------------------------------------------------------------------
// A RAII helper for writing to the LogInstance
//
class Log : public Uncopyable
{
public:
@@ -105,47 +164,11 @@ public:
return oss;
}
public:
static std::string severityToString (LogSeverity);
static LogSeverity stringToSeverity (std::string const&);
static LogSeverity getMinSeverity ();
static void setMinSeverity (LogSeverity, bool all);
static void setLogFile (boost::filesystem::path const& pathToLogFile);
/** Rotate the log file.
The log file is closed and reopened. This is for compatibility
with log management tools.
@return A human readable string describing the result of the operation.
*/
static std::string rotateLog ();
public:
/** Write to log output.
All logging eventually goes through this function. If a
debugger is attached, the string goes to the debugging console,
else it goes to the standard error output. If a log file is
open, then the message is additionally written to the open log
file.
The text should not contain a newline, it will be automatically
added as needed.
@note This acquires a global mutex.
@param text The text to write.
@param toStdErr `true` to also write to std::cerr
*/
static void print (std::string const& text,
bool toStdErr = true);
static void print (StringArray const& strings, bool toStdErr = true);
/** Output stream for logging
This is a convenient replacement for writing to `std::cerr`.
@@ -169,7 +192,7 @@ public:
~out ()
{
Log::print (m_ss.str ());
LogInstance::getInstance()->print (m_ss.str ());
}
template <class T>
@@ -196,15 +219,6 @@ private:
static std::string replaceFirstSecretWithAsterisks (std::string s);
// Singleton variables
//
typedef RippleRecursiveMutex StaticLockType;
typedef StaticLockType::ScopedLockType StaticScopedLockType;
static StaticLockType s_lock;
static LogFile s_logFile;
static LogSeverity sMinSeverity;
mutable std::ostringstream oss;
LogSeverity mSeverity;
std::string mPartitionName;
@@ -223,5 +237,3 @@ private:
#define CondLog(c, s, k) if (!ShouldLog (s, k) || !(c)) do {} while(0); else Log(s, LogPartition::get <k> ())
#endif
// vim:ts=4