Refactor Log code, add LogJournal adapter

This commit is contained in:
Vinnie Falco
2013-09-12 15:03:39 -07:00
parent 5038a65acd
commit b839ae0552
25 changed files with 802 additions and 577 deletions

View File

@@ -659,6 +659,36 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\Log.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogFile.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogJournal.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogPartition.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogSink.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\ripple_basics.cpp" />
<ClCompile Include="..\..\src\ripple_basics\types\ripple_UInt256.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -690,18 +720,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\utility\ripple_Log.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\utility\ripple_LogFile.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\utility\ripple_RandomNumbers.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -1497,6 +1515,13 @@
<ClInclude Include="..\..\src\ripple_basics\json\json_reader.h" />
<ClInclude Include="..\..\src\ripple_basics\json\json_value.h" />
<ClInclude Include="..\..\src\ripple_basics\json\json_writer.h" />
<ClInclude Include="..\..\src\ripple_basics\log\Log.h" />
<ClInclude Include="..\..\src\ripple_basics\log\LogFile.h" />
<ClInclude Include="..\..\src\ripple_basics\log\LoggedTimings.h" />
<ClInclude Include="..\..\src\ripple_basics\log\LogJournal.h" />
<ClInclude Include="..\..\src\ripple_basics\log\LogPartition.h" />
<ClInclude Include="..\..\src\ripple_basics\log\LogSeverity.h" />
<ClInclude Include="..\..\src\ripple_basics\log\LogSink.h" />
<ClInclude Include="..\..\src\ripple_basics\ripple_basics.h" />
<ClInclude Include="..\..\src\ripple_basics\system\ripple_BoostIncludes.h" />
<ClInclude Include="..\..\src\ripple_basics\system\ripple_OpenSSLIncludes.h" />
@@ -1509,15 +1534,12 @@
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_DiffieHellmanUtil.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_HashUtilities.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_IniFile.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_Log.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_LogFile.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_PlatformMacros.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_RandomNumbers.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_StringUtilities.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_Sustain.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_ThreadName.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_Time.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_LoggedTimings.h" />
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_UptimeTimer.h" />
<ClInclude Include="..\..\src\ripple_core\functional\LoadSource.h" />
<ClInclude Include="..\..\src\ripple_core\functional\LoadType.h" />

View File

@@ -172,6 +172,9 @@
<Filter Include="[2] Ripple %28New%29\testoverlay\impl">
<UniqueIdentifier>{e614b68f-21cb-4866-82d1-1ea89ee11906}</UniqueIdentifier>
</Filter>
<Filter Include="[1] Ripple\ripple_basics\log">
<UniqueIdentifier>{824b1f04-7313-4abb-a3db-6241c7c8a356}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\ripple_basics\containers\ripple_RangeSet.cpp">
@@ -195,9 +198,6 @@
<ClCompile Include="..\..\src\ripple_basics\utility\ripple_IniFile.cpp">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\utility\ripple_Log.cpp">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\utility\ripple_RandomNumbers.cpp">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClCompile>
@@ -498,9 +498,6 @@
<ClCompile Include="..\..\src\ripple_app\ripple_app_pt8.cpp">
<Filter>[1] Ripple\ripple_app</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\utility\ripple_LogFile.cpp">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_data\protocol\ripple_LedgerFormats.cpp">
<Filter>[1] Ripple\ripple_data\protocol</Filter>
</ClCompile>
@@ -903,6 +900,21 @@
<ClCompile Include="..\..\src\ripple_app\main\FatalErrorReporter.cpp">
<Filter>[1] Ripple\ripple_app\main</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\Log.cpp">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogFile.cpp">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogJournal.cpp">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogSink.cpp">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_basics\log\LogPartition.cpp">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\ripple_app\ripple_app.h">
@@ -953,9 +965,6 @@
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_IniFile.h">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_Log.h">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_PlatformMacros.h">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClInclude>
@@ -1280,9 +1289,6 @@
<ClInclude Include="..\..\src\leveldb\port\port_posix.h">
<Filter>[0] Libraries\leveldb\port</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_LogFile.h">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_data\protocol\ripple_KnownFormats.h">
<Filter>[1] Ripple\ripple_data\protocol</Filter>
</ClInclude>
@@ -1520,9 +1526,6 @@
<ClInclude Include="..\..\src\ripple_app\main\ripple_RippleMain.h">
<Filter>[1] Ripple\ripple_app\main</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\utility\ripple_LoggedTimings.h">
<Filter>[1] Ripple\ripple_basics\utility</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_app\websocket\WSConnection.h">
<Filter>[1] Ripple\ripple_app\websocket</Filter>
</ClInclude>
@@ -1761,6 +1764,27 @@
<ClInclude Include="..\..\src\ripple_app\main\FatalErrorReporter.h">
<Filter>[1] Ripple\ripple_app\main</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\log\Log.h">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\log\LogFile.h">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\log\LoggedTimings.h">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\log\LogJournal.h">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\log\LogSink.h">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\log\LogSeverity.h">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_basics\log\LogPartition.h">
<Filter>[1] Ripple\ripple_basics\log</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">

View File

@@ -3,6 +3,11 @@ RIPPLE TODO
--------------------------------------------------------------------------------
Vinnie's List: Changes day to day, descending priority
- Fix and tidy up broken beast classes
- Parse Validator line using cribbed code
- Parse ContentBodyBuffer from HTTPResponse
- General cleanup of the repository and projcet files
- Look into using CMake
- Validators should delay the application of newly downloaded lists from
sources, to mitigate the effects of attacks. Unless there's no validators

View File

@@ -11,6 +11,15 @@ class Application;
SETUP_LOG (Application)
//------------------------------------------------------------------------------
//
// Specializations for LogPartition names
template <> char const* LogPartition::getPartitionName <Validators> () { return "Validators"; }
//
//------------------------------------------------------------------------------
// VFALCO TODO Move the function definitions into the class declaration
class ApplicationImp
: public Application
@@ -475,9 +484,9 @@ public:
if (!getConfig ().DEBUG_LOGFILE.empty ())
{
// Let debug messages go to the file but only WARNING or higher to regular output (unless verbose)
LogInstance::getInstance()->setLogFile (getConfig ().DEBUG_LOGFILE);
LogSink::get()->setLogFile (getConfig ().DEBUG_LOGFILE);
if (LogInstance::getInstance()->getMinSeverity () > lsDEBUG)
if (LogSink::get()->getMinSeverity () > lsDEBUG)
LogPartition::setSeverity (lsDEBUG);
}

View File

@@ -360,15 +360,15 @@ int RippleMain::run (int argc, char const* const* argv)
if (vm.count ("quiet"))
{
LogInstance::getInstance()->setMinSeverity (lsFATAL, true);
LogSink::get()->setMinSeverity (lsFATAL, true);
}
else if (vm.count ("verbose"))
{
LogInstance::getInstance()->setMinSeverity (lsTRACE, true);
LogSink::get()->setMinSeverity (lsTRACE, true);
}
else
{
LogInstance::getInstance()->setMinSeverity (lsINFO, true);
LogSink::get()->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;
LogInstance::getInstance()->setMinSeverity(lsFATAL,true);
LogSink::get()->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 LogInstance::getInstance()->rotateLog ();
return LogSink::get()->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 (LogInstance::getInstance()->getMinSeverity ());
lev["base"] = Log::severityToString (LogSink::get()->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
LogInstance::getInstance()->setMinSeverity (sv, true);
LogSink::get()->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"))
LogInstance::getInstance()->setMinSeverity (sv, false);
LogSink::get()->setMinSeverity (sv, false);
else if (!LogPartition::setSeverity (partition, sv))
return rpcError (rpcINVALID_PARAMS);

View File

@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
std::string Log::replaceFirstSecretWithAsterisks (std::string s)
{
using namespace std;
char const* secretToken = "\"secret\"";
// Look for the first occurrence of "secret" in the string.
//
size_t startingPosition = s.find (secretToken);
if (startingPosition != string::npos)
{
// Found it, advance past the token.
//
startingPosition += strlen (secretToken);
// Replace the next 35 characters at most, without overwriting the end.
//
size_t endingPosition = std::min (startingPosition + 35, s.size () - 1);
for (size_t i = startingPosition; i < endingPosition; ++i)
s [i] = '*';
}
return s;
}
//------------------------------------------------------------------------------
Log::~Log ()
{
LogSink::get()->write (oss.str(), mSeverity, mPartitionName);
}
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;
}

100
src/ripple_basics/log/Log.h Normal file
View File

@@ -0,0 +1,100 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_BASICS_LOG_H_INCLUDED
#define RIPPLE_BASICS_LOG_H_INCLUDED
// A RAII helper for writing to the LogSink
//
class Log : public Uncopyable
{
public:
explicit Log (LogSeverity s) : mSeverity (s)
{
}
Log (LogSeverity s, LogPartition const& p)
: mSeverity (s)
, mPartitionName (p.getName ())
{
}
~Log ();
template <class T>
std::ostream& operator<< (const T& t) const
{
return oss << t;
}
std::ostringstream& ref () const
{
return oss;
}
public:
static std::string severityToString (LogSeverity);
static LogSeverity stringToSeverity (std::string const&);
/** Output stream for logging
This is a convenient replacement for writing to `std::cerr`.
Usage:
@code
Log::out () << "item1" << 2;
@endcode
It is not necessary to append a newline.
*/
class out
{
public:
out ()
{
}
~out ()
{
LogSink::get()->write (m_ss.str ());
}
template <class T>
out& operator<< (T t)
{
m_ss << t;
return *this;
}
private:
std::stringstream m_ss;
};
private:
static std::string replaceFirstSecretWithAsterisks (std::string s);
mutable std::ostringstream oss;
LogSeverity mSeverity;
std::string mPartitionName;
};
// Manually test for whether we should log
//
#define ShouldLog(s, k) (LogPartition::get <k> ().doLog (s))
// Write to the log at the given severity level
//
#define WriteLog(s, k) if (!ShouldLog (s, k)) do {} while (0); else Log (s, LogPartition::get <k> ())
// Write to the log conditionally
//
#define CondLog(c, s, k) if (!ShouldLog (s, k) || !(c)) do {} while(0); else Log(s, LogPartition::get <k> ())
#endif

View File

@@ -4,8 +4,8 @@
*/
//==============================================================================
#ifndef RIPPLE_LOGFILE_H_INCLUDED
#define RIPPLE_LOGFILE_H_INCLUDED
#ifndef RIPPLE_BASICS_LOGFILE_H_INCLUDED
#define RIPPLE_BASICS_LOGFILE_H_INCLUDED
/** Manages a system file containing logged output.

View File

@@ -0,0 +1,24 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
LogSeverity LogJournal::convertSeverity (Journal::Severity severity)
{
switch (severity)
{
case Journal::kTrace: return lsTRACE;
case Journal::kDebug: return lsDEBUG;
case Journal::kInfo: return lsINFO;
case Journal::kWarning: return lsWARNING;
case Journal::kError: return lsERROR;
default:
bassertfalse;
case Journal::kFatal:
break;
}
return lsFATAL;
}

View File

@@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_BASICS_LOGJOURNAL_H_INCLUDED
#define RIPPLE_BASICS_LOGJOURNAL_H_INCLUDED
/** Adapter that exports ripple::Log functionality as a Journal::Sink. */
class LogJournal
{
public:
/** Convert the Journal::Severity to a LogSeverity. */
static LogSeverity convertSeverity (Journal::Severity severity);
//--------------------------------------------------------------------------
/** A Journal::Sink that writes to the LogPartition with a given Key. */
template <class Key>
class PartitionSink : public Journal::Sink
{
public:
PartitionSink ()
: m_partition (LogPartition::get <Key> ())
{
}
void write (Journal::Severity severity, std::string const& text)
{
// FIXME!
LogSink::get()->write (text, convertSeverity (severity), m_partition.getName());
}
bool active (Journal::Severity severity)
{
return m_partition.doLog (convertSeverity (severity));
}
private:
LogPartition const& m_partition;
};
//--------------------------------------------------------------------------
/** Returns a Journal outputting through the LogPartition for the Key. */
template <class Key>
static Journal get ()
{
return Journal (SharedSingleton <PartitionSink <Key> >::get (
SingletonLifetime::neverDestroyed));
}
};
#endif

View File

@@ -0,0 +1,52 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
LogPartition* LogPartition::headLog = NULL;
LogPartition::LogPartition (char const* partitionName)
: mNextLog (headLog)
, mMinSeverity (lsWARNING)
{
const char* ptr = strrchr (partitionName, '/');
mName = (ptr == NULL) ? partitionName : (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<std::string, std::string> > LogPartition::getSeverities ()
{
std::vector< std::pair<std::string, std::string> > sevs;
for (LogPartition* l = headLog; l != NULL; l = l->mNextLog)
sevs.push_back (std::make_pair (l->mName, Log::severityToString (l->mMinSeverity)));
return sevs;
}
//------------------------------------------------------------------------------
bool LogPartition::setSeverity (const std::string& partition, LogSeverity severity)
{
for (LogPartition* p = headLog; p != NULL; p = p->mNextLog)
if (boost::iequals (p->mName, partition))
{
p->mMinSeverity = severity;
return true;
}
return false;
}
void LogPartition::setSeverity (LogSeverity severity)
{
for (LogPartition* p = headLog; p != NULL; p = p->mNextLog)
p->mMinSeverity = severity;
}

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_BASICS_LOGPARTITION_H_INCLUDED
#define RIPPLE_BASICS_LOGPARTITION_H_INCLUDED
class LogPartition // : public List <LogPartition>::Node
{
public:
LogPartition (const char* partitionName);
/** Retrieve the LogPartition associated with an object.
Each LogPartition is a singleton.
*/
template <class Key>
static LogPartition const& get ()
{
struct LogPartitionType : LogPartition
{
LogPartitionType () : LogPartition (getPartitionName <Key> ())
{
}
};
return *SharedSingleton <LogPartitionType>::getInstance();
}
bool doLog (LogSeverity s) const
{
return s >= mMinSeverity;
}
const std::string& getName () const
{
return mName;
}
static bool setSeverity (const std::string& partition, LogSeverity severity);
static void setSeverity (LogSeverity severity);
static std::vector< std::pair<std::string, std::string> > getSeverities ();
private:
/** Retrieve the name for a log partition.
*/
template <class Key>
static char const* getPartitionName ();
private:
// VFALCO TODO Use an intrusive linked list
//
static LogPartition* headLog;
LogPartition* mNextLog;
LogSeverity mMinSeverity;
std::string mName;
};
#define SETUP_LOG(Class) \
template <> char const* LogPartition::getPartitionName <Class> () { return #Class; } \
struct Class##Instantiator { Class##Instantiator () { LogPartition::get <Class> (); } }; \
static Class##Instantiator Class##Instantiator_instance;
#define SETUP_LOGN(Class,Name) \
template <> char const* LogPartition::getPartitionName <Class> () { return Name; } \
struct Class##Instantiator { Class##Instantiator () { LogPartition::get <Class> (); } }; \
static Class##Instantiator Class##Instantiator_instance;
#endif

View File

@@ -0,0 +1,21 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_BASICS_LOGSEVERITY_H_INCLUDED
#define RIPPLE_BASICS_LOGSEVERITY_H_INCLUDED
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
lsWARNING = 3, // Conditions that warrant human attention, may indicate a problem
lsERROR = 4, // A condition that indicates a problem
lsFATAL = 5 // A severe condition that indicates a server problem
};
#endif

View File

@@ -0,0 +1,176 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
LogSink::LogSink ()
: m_mutex ("Log", __FILE__, __LINE__)
, m_minSeverity (lsINFO)
{
}
LogSink::~LogSink ()
{
}
LogSeverity LogSink::getMinSeverity ()
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
return m_minSeverity;
}
void LogSink::setMinSeverity (LogSeverity s, bool all)
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
m_minSeverity = s;
if (all)
LogPartition::setSeverity (s);
}
void LogSink::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 LogSink::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 LogSink::write (
std::string const& message,
LogSeverity severity,
std::string const& partitionName)
{
std::string text;
text.reserve (message.size() + partitionName.size() + 100);
text = boost::posix_time::to_simple_string (
boost::posix_time::second_clock::universal_time ());
text += " ";
if (! partitionName.empty ())
text += partitionName + ":";
switch (severity)
{
case lsTRACE: text += "TRC "; break;
case lsDEBUG: text += "DBG "; break;
case lsINFO: text += "NFO "; break;
case lsWARNING: text += "WRN "; break;
case lsERROR: text += "ERR "; break;
default:
bassertfalse;
case lsFATAL: text += "FTL ";
break;
}
text += replaceFirstSecretWithAsterisks (message);
if (text.size() > maximumMessageCharacters)
{
text.resize (maximumMessageCharacters - 3);
text += "...";
}
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
write (text, severity >= getMinSeverity(), lock);
}
}
void LogSink::write (std::string const& text)
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
write (text, true, lock);
}
void LogSink::write (StringArray const& strings)
{
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
for (int i = 0; i < strings.size (); ++i)
write (strings [i].toStdString (), true, lock);
}
void LogSink::write (std::string const& line, bool toStdErr, ScopedLockType&)
{
// Does nothing if not open.
m_logFile.writeln (line);
if (toStdErr)
{
#if BEAST_MSVC
if (beast_isRunningUnderDebugger ())
{
// Send it to the attached debugger's Output window
//
Logger::outputDebugString (line);
}
else
#endif
{
std::cerr << line << std::endl;
}
}
}
//------------------------------------------------------------------------------
std::string LogSink::replaceFirstSecretWithAsterisks (std::string s)
{
using namespace std;
char const* secretToken = "\"secret\"";
// Look for the first occurrence of "secret" in the string.
//
size_t startingPosition = s.find (secretToken);
if (startingPosition != string::npos)
{
// Found it, advance past the token.
//
startingPosition += strlen (secretToken);
// Replace the next 35 characters at most, without overwriting the end.
//
size_t endingPosition = std::min (startingPosition + 35, s.size () - 1);
for (size_t i = startingPosition; i < endingPosition; ++i)
s [i] = '*';
}
return s;
}
//------------------------------------------------------------------------------
LogSink::Ptr LogSink::get ()
{
return SharedSingleton <LogSink>::getInstance ();
}

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_BASICS_LOGSINK_H_INCLUDED
#define RIPPLE_BASICS_LOGSINK_H_INCLUDED
/** An endpoint for all logging messages. */
class LogSink
{
public:
LogSink ();
~LogSink ();
/** Returns the minimum severity required for also writing to stderr. */
LogSeverity getMinSeverity ();
/** Sets the minimum severity required for also writing to stderr. */
void setMinSeverity (LogSeverity, bool all);
/** Sets the path to the log file. */
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 write (std::string const& message,
LogSeverity severity, std::string const& partitionName);
void write (std::string const& text);
void write (StringArray const& strings);
/** @} */
/** Hides secret keys from log output. */
static std::string replaceFirstSecretWithAsterisks (std::string s);
/** Returns a pointer to the singleton. */
typedef SharedPtr <SharedSingleton <LogSink> > Ptr;
static Ptr get ();
private:
typedef RippleRecursiveMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
enum
{
/** Maximum line length for log messages.
If the message exceeds this length it will be truncated with elipses.
*/
maximumMessageCharacters = 12 * 1024
};
void write (std::string const& line, bool toStdErr, ScopedLockType&);
LockType m_mutex;
LogFile m_logFile;
LogSeverity m_minSeverity;
};
#endif

View File

@@ -4,8 +4,8 @@
*/
//==============================================================================
#ifndef RIPPLE_LOGGEDTIMINGS_H_INCLUDED
#define RIPPLE_LOGGEDTIMINGS_H_INCLUDED
#ifndef RIPPLE_BASICS_LOGGEDTIMINGS_H_INCLUDED
#define RIPPLE_BASICS_LOGGEDTIMINGS_H_INCLUDED
namespace detail
{

View File

@@ -79,8 +79,11 @@ namespace ripple
#include "json/json_value.cpp"
#include "json/json_writer.cpp"
#include "utility/ripple_Log.cpp"
#include "utility/ripple_LogFile.cpp"
#include "log/Log.cpp"
#include "log/LogFile.cpp"
#include "log/LogJournal.cpp"
#include "log/LogPartition.cpp"
#include "log/LogSink.cpp"
#include "utility/ripple_ByteOrder.cpp"
#include "utility/ripple_CountedObject.cpp"

View File

@@ -94,8 +94,13 @@ using namespace beast;
#include "types/ripple_BasicTypes.h"
#include "utility/ripple_LogFile.h"
#include "utility/ripple_Log.h" // Needed by others
# include "log/LogSeverity.h"
# include "log/LogFile.h"
# include "log/LogSink.h"
# include "log/LogPartition.h"
# include "log/Log.h"
#include "log/LogJournal.h"
#include "log/LoggedTimings.h"
#include "utility/ripple_ByteOrder.h"
#include "utility/ripple_CountedObject.h"
@@ -107,7 +112,6 @@ using namespace beast;
#include "utility/ripple_Sustain.h"
#include "utility/ripple_ThreadName.h"
#include "utility/ripple_Time.h"
#include "utility/ripple_LoggedTimings.h"
#include "utility/ripple_UptimeTimer.h"
#include "types/ripple_UInt256.h"

View File

@@ -35,4 +35,5 @@ typedef UnsignedInteger <33> RipplePublicKey;
/** A container holding the hash of a public key in binary format. */
typedef UnsignedInteger <20> RipplePublicKeyHash;
#endif

View File

@@ -1,282 +0,0 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
LogPartition* LogPartition::headLog = NULL;
LogPartition::LogPartition (char const* partitionName)
: mNextLog (headLog)
, mMinSeverity (lsWARNING)
{
const char* ptr = strrchr (partitionName, '/');
mName = (ptr == NULL) ? partitionName : (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<std::string, std::string> > LogPartition::getSeverities ()
{
std::vector< std::pair<std::string, std::string> > sevs;
for (LogPartition* l = headLog; l != NULL; l = l->mNextLog)
sevs.push_back (std::make_pair (l->mName, Log::severityToString (l->mMinSeverity)));
return sevs;
}
//------------------------------------------------------------------------------
std::string Log::replaceFirstSecretWithAsterisks (std::string s)
{
using namespace std;
char const* secretToken = "\"secret\"";
// Look for the first occurrence of "secret" in the string.
//
size_t startingPosition = s.find (secretToken);
if (startingPosition != string::npos)
{
// Found it, advance past the token.
//
startingPosition += strlen (secretToken);
// Replace the next 35 characters at most, without overwriting the end.
//
size_t endingPosition = std::min (startingPosition + 35, s.size () - 1);
for (size_t i = startingPosition; i < endingPosition; ++i)
s [i] = '*';
}
return s;
}
//------------------------------------------------------------------------------
Log::~Log ()
{
std::string logMsg = boost::posix_time::to_simple_string (boost::posix_time::second_clock::universal_time ());
if (!mPartitionName.empty ())
logMsg += " " + mPartitionName + ":";
else
logMsg += " ";
switch (mSeverity)
{
case lsTRACE:
logMsg += "TRC ";
break;
case lsDEBUG:
logMsg += "DBG ";
break;
case lsINFO:
logMsg += "NFO ";
break;
case lsWARNING:
logMsg += "WRN ";
break;
case lsERROR:
logMsg += "ERR ";
break;
case lsFATAL:
logMsg += "FTL ";
break;
case lsINVALID:
assert (false);
return;
}
logMsg += replaceFirstSecretWithAsterisks (oss.str ());
if (logMsg.size () > maximumMessageCharacters)
{
logMsg.resize (maximumMessageCharacters);
logMsg += "...";
}
LogInstance::getInstance()->print (logMsg, mSeverity >= LogInstance::getInstance()->getMinSeverity ());
}
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;
}
bool LogPartition::setSeverity (const std::string& partition, LogSeverity severity)
{
for (LogPartition* p = headLog; p != NULL; p = p->mNextLog)
if (boost::iequals (p->mName, partition))
{
p->mMinSeverity = severity;
return true;
}
return false;
}
void LogPartition::setSeverity (LogSeverity severity)
{
for (LogPartition* p = headLog; p != NULL; p = p->mNextLog)
p->mMinSeverity = severity;
}
//------------------------------------------------------------------------------
LogInstance::LogInstance ()
: m_mutex ("Log", __FILE__, __LINE__)
, m_minSeverity (lsINFO)
{
}
LogInstance::~LogInstance ()
{
}
LogInstance* LogInstance::getInstance ()
{
return SharedSingleton <LogInstance>::getInstance ();
}
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

@@ -1,246 +0,0 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_LOG_H_INCLUDED
#define RIPPLE_LOG_H_INCLUDED
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
lsWARNING = 3, // Conditions that warrant human attention, may indicate a problem
lsERROR = 4, // A condition that indicates a problem
lsFATAL = 5 // A severe condition that indicates a server problem
};
//------------------------------------------------------------------------------
// VFALCO TODO make this a nested class in Log?
class LogPartition // : public List <LogPartition>::Node
{
public:
LogPartition (const char* partitionName);
/** Retrieve the LogPartition associated with an object.
Each LogPartition is a singleton.
*/
template <class Key>
static LogPartition const& get ()
{
struct LogPartitionType : LogPartition
{
LogPartitionType () : LogPartition (getPartitionName <Key> ())
{
}
};
return *SharedSingleton <LogPartitionType>::getInstance();
}
bool doLog (LogSeverity s) const
{
return s >= mMinSeverity;
}
const std::string& getName () const
{
return mName;
}
static bool setSeverity (const std::string& partition, LogSeverity severity);
static void setSeverity (LogSeverity severity);
static std::vector< std::pair<std::string, std::string> > getSeverities ();
private:
/** Retrieve the name for a log partition.
*/
template <class Key>
static char const* getPartitionName ();
private:
// VFALCO TODO Use an intrusive linked list
//
static LogPartition* headLog;
LogPartition* mNextLog;
LogSeverity mMinSeverity;
std::string mName;
};
#define SETUP_LOG(Class) \
template <> char const* LogPartition::getPartitionName <Class> () { return #Class; } \
struct Class##Instantiator { Class##Instantiator () { LogPartition::get <Class> (); } }; \
static Class##Instantiator Class##Instantiator_instance;
#define SETUP_LOGN(Class,Name) \
template <> char const* LogPartition::getPartitionName <Class> () { return Name; } \
struct Class##Instantiator { Class##Instantiator () { LogPartition::get <Class> (); } }; \
static Class##Instantiator Class##Instantiator_instance;
//------------------------------------------------------------------------------
// A singleton which performs the actual logging.
//
class LogInstance
{
public:
LogInstance ();
~LogInstance ();
static LogInstance* getInstance ();
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:
explicit Log (LogSeverity s) : mSeverity (s)
{
}
Log (LogSeverity s, LogPartition const& p)
: mSeverity (s)
, mPartitionName (p.getName ())
{
}
~Log ();
template <class T>
std::ostream& operator<< (const T& t) const
{
return oss << t;
}
std::ostringstream& ref () const
{
return oss;
}
public:
static std::string severityToString (LogSeverity);
static LogSeverity stringToSeverity (std::string const&);
/** Output stream for logging
This is a convenient replacement for writing to `std::cerr`.
Usage:
@code
Log::out () << "item1" << 2;
@endcode
It is not necessary to append a newline.
*/
class out
{
public:
out ()
{
}
~out ()
{
LogInstance::getInstance()->print (m_ss.str ());
}
template <class T>
out& operator<< (T t)
{
m_ss << t;
return *this;
}
private:
std::stringstream m_ss;
};
private:
enum
{
/** Maximum line length for log messages.
If the message exceeds this length it will be truncated
with elipses.
*/
maximumMessageCharacters = 12 * 1024
};
static std::string replaceFirstSecretWithAsterisks (std::string s);
mutable std::ostringstream oss;
LogSeverity mSeverity;
std::string mPartitionName;
};
// Manually test for whether we should log
//
#define ShouldLog(s, k) (LogPartition::get <k> ().doLog (s))
// Write to the log at the given severity level
//
#define WriteLog(s, k) if (!ShouldLog (s, k)) do {} while (0); else Log (s, LogPartition::get <k> ())
// Write to the log conditionally
//
#define CondLog(c, s, k) if (!ShouldLog (s, k) || !(c)) do {} while(0); else Log(s, LogPartition::get <k> ())
#endif

View File

@@ -12,6 +12,15 @@ RippleAddress::RippleAddress ()
nVersion = VER_NONE;
}
RipplePublicKey RippleAddress::toRipplePublicKey () const
{
Blob const& b (getNodePublic ());
check_precondition (b.size () == RipplePublicKey::sizeInBytes);
return RipplePublicKey (&b [0]);
}
void RippleAddress::clear ()
{
nVersion = VER_NONE;

View File

@@ -31,6 +31,11 @@ private:
public:
RippleAddress ();
// Convert to a binary public key. If the underlying data
// is not appropriate, this will cause a fatal error.
//
RipplePublicKey toRipplePublicKey () const;
// For public and private key, checks if they are legal.
bool isValid () const
{