diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index 95eb9aabdb..fc57846603 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj
+++ b/Builds/VisualStudio2012/RippleD.vcxproj
@@ -659,6 +659,36 @@
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
@@ -690,18 +720,6 @@
true
true
-
- true
- true
- true
- true
-
-
- true
- true
- true
- true
-
true
true
@@ -1497,6 +1515,13 @@
+
+
+
+
+
+
+
@@ -1509,15 +1534,12 @@
-
-
-
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters
index 8c41e44a0d..7c746036d9 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters
@@ -172,6 +172,9 @@
{e614b68f-21cb-4866-82d1-1ea89ee11906}
+
+ {824b1f04-7313-4abb-a3db-6241c7c8a356}
+
@@ -195,9 +198,6 @@
[1] Ripple\ripple_basics\utility
-
- [1] Ripple\ripple_basics\utility
-
[1] Ripple\ripple_basics\utility
@@ -498,9 +498,6 @@
[1] Ripple\ripple_app
-
- [1] Ripple\ripple_basics\utility
-
[1] Ripple\ripple_data\protocol
@@ -903,6 +900,21 @@
[1] Ripple\ripple_app\main
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
@@ -953,9 +965,6 @@
[1] Ripple\ripple_basics\utility
-
- [1] Ripple\ripple_basics\utility
-
[1] Ripple\ripple_basics\utility
@@ -1280,9 +1289,6 @@
[0] Libraries\leveldb\port
-
- [1] Ripple\ripple_basics\utility
-
[1] Ripple\ripple_data\protocol
@@ -1520,9 +1526,6 @@
[1] Ripple\ripple_app\main
-
- [1] Ripple\ripple_basics\utility
-
[1] Ripple\ripple_app\websocket
@@ -1761,6 +1764,27 @@
[1] Ripple\ripple_app\main
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
+
+ [1] Ripple\ripple_basics\log
+
diff --git a/doc/todo/VFALCO_TODO.txt b/doc/todo/VFALCO_TODO.txt
index 5f8f70707a..32b3160b1d 100644
--- a/doc/todo/VFALCO_TODO.txt
+++ b/doc/todo/VFALCO_TODO.txt
@@ -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
diff --git a/src/ripple_app/main/ripple_Application.cpp b/src/ripple_app/main/ripple_Application.cpp
index 80a6e7f659..8a69f98b7d 100644
--- a/src/ripple_app/main/ripple_Application.cpp
+++ b/src/ripple_app/main/ripple_Application.cpp
@@ -11,6 +11,15 @@ class Application;
SETUP_LOG (Application)
+//------------------------------------------------------------------------------
+//
+// Specializations for LogPartition names
+
+template <> char const* LogPartition::getPartitionName () { 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);
}
diff --git a/src/ripple_app/main/ripple_RippleMain.cpp b/src/ripple_app/main/ripple_RippleMain.cpp
index 67fc5bc593..a9ec433a36 100644
--- a/src/ripple_app/main/ripple_RippleMain.cpp
+++ b/src/ripple_app/main/ripple_RippleMain.cpp
@@ -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.
diff --git a/src/ripple_app/rpc/RPCHandler.cpp b/src/ripple_app/rpc/RPCHandler.cpp
index cd34247c78..e93ff2acc6 100644
--- a/src/ripple_app/rpc/RPCHandler.cpp
+++ b/src/ripple_app/rpc/RPCHandler.cpp
@@ -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 > logTable = LogPartition::getSeverities ();
typedef std::map::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);
diff --git a/src/ripple_basics/log/Log.cpp b/src/ripple_basics/log/Log.cpp
new file mode 100644
index 0000000000..e95ede65ed
--- /dev/null
+++ b/src/ripple_basics/log/Log.cpp
@@ -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;
+}
diff --git a/src/ripple_basics/log/Log.h b/src/ripple_basics/log/Log.h
new file mode 100644
index 0000000000..c0e8b754cf
--- /dev/null
+++ b/src/ripple_basics/log/Log.h
@@ -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
+ 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
+ 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 ().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 ())
+
+// Write to the log conditionally
+//
+#define CondLog(c, s, k) if (!ShouldLog (s, k) || !(c)) do {} while(0); else Log(s, LogPartition::get ())
+
+#endif
diff --git a/src/ripple_basics/utility/ripple_LogFile.cpp b/src/ripple_basics/log/LogFile.cpp
similarity index 100%
rename from src/ripple_basics/utility/ripple_LogFile.cpp
rename to src/ripple_basics/log/LogFile.cpp
diff --git a/src/ripple_basics/utility/ripple_LogFile.h b/src/ripple_basics/log/LogFile.h
similarity index 96%
rename from src/ripple_basics/utility/ripple_LogFile.h
rename to src/ripple_basics/log/LogFile.h
index ca9bc34db1..e77b363835 100644
--- a/src/ripple_basics/utility/ripple_LogFile.h
+++ b/src/ripple_basics/log/LogFile.h
@@ -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.
diff --git a/src/ripple_basics/log/LogJournal.cpp b/src/ripple_basics/log/LogJournal.cpp
new file mode 100644
index 0000000000..fba76bbb90
--- /dev/null
+++ b/src/ripple_basics/log/LogJournal.cpp
@@ -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;
+}
diff --git a/src/ripple_basics/log/LogJournal.h b/src/ripple_basics/log/LogJournal.h
new file mode 100644
index 0000000000..f7f349364e
--- /dev/null
+++ b/src/ripple_basics/log/LogJournal.h
@@ -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 PartitionSink : public Journal::Sink
+ {
+ public:
+ PartitionSink ()
+ : m_partition (LogPartition::get ())
+ {
+ }
+
+ 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
+ static Journal get ()
+ {
+ return Journal (SharedSingleton >::get (
+ SingletonLifetime::neverDestroyed));
+ }
+};
+
+#endif
diff --git a/src/ripple_basics/log/LogPartition.cpp b/src/ripple_basics/log/LogPartition.cpp
new file mode 100644
index 0000000000..7efd65e821
--- /dev/null
+++ b/src/ripple_basics/log/LogPartition.cpp
@@ -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 > 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;
+}
+
+//------------------------------------------------------------------------------
+
+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;
+}
diff --git a/src/ripple_basics/log/LogPartition.h b/src/ripple_basics/log/LogPartition.h
new file mode 100644
index 0000000000..3244c3fdc3
--- /dev/null
+++ b/src/ripple_basics/log/LogPartition.h
@@ -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 ::Node
+{
+public:
+ LogPartition (const char* partitionName);
+
+ /** Retrieve the LogPartition associated with an object.
+
+ Each LogPartition is a singleton.
+ */
+ template
+ static LogPartition const& get ()
+ {
+ struct LogPartitionType : LogPartition
+ {
+ LogPartitionType () : LogPartition (getPartitionName ())
+ {
+ }
+ };
+
+ return *SharedSingleton ::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 > getSeverities ();
+
+private:
+ /** Retrieve the name for a log partition.
+ */
+ template
+ 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 () { return #Class; } \
+ struct Class##Instantiator { Class##Instantiator () { LogPartition::get (); } }; \
+ static Class##Instantiator Class##Instantiator_instance;
+
+#define SETUP_LOGN(Class,Name) \
+ template <> char const* LogPartition::getPartitionName () { return Name; } \
+ struct Class##Instantiator { Class##Instantiator () { LogPartition::get (); } }; \
+ static Class##Instantiator Class##Instantiator_instance;
+
+#endif
diff --git a/src/ripple_basics/log/LogSeverity.h b/src/ripple_basics/log/LogSeverity.h
new file mode 100644
index 0000000000..cacd35365c
--- /dev/null
+++ b/src/ripple_basics/log/LogSeverity.h
@@ -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
diff --git a/src/ripple_basics/log/LogSink.cpp b/src/ripple_basics/log/LogSink.cpp
new file mode 100644
index 0000000000..0c3e1ca43e
--- /dev/null
+++ b/src/ripple_basics/log/LogSink.cpp
@@ -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 ::getInstance ();
+}
+
diff --git a/src/ripple_basics/log/LogSink.h b/src/ripple_basics/log/LogSink.h
new file mode 100644
index 0000000000..2f35e1ffbb
--- /dev/null
+++ b/src/ripple_basics/log/LogSink.h
@@ -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 > 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
diff --git a/src/ripple_basics/utility/ripple_LoggedTimings.h b/src/ripple_basics/log/LoggedTimings.h
similarity index 96%
rename from src/ripple_basics/utility/ripple_LoggedTimings.h
rename to src/ripple_basics/log/LoggedTimings.h
index ddc933f4bc..c2e17b055f 100644
--- a/src/ripple_basics/utility/ripple_LoggedTimings.h
+++ b/src/ripple_basics/log/LoggedTimings.h
@@ -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
{
diff --git a/src/ripple_basics/ripple_basics.cpp b/src/ripple_basics/ripple_basics.cpp
index 6de88267e2..86f38a93a3 100644
--- a/src/ripple_basics/ripple_basics.cpp
+++ b/src/ripple_basics/ripple_basics.cpp
@@ -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"
diff --git a/src/ripple_basics/ripple_basics.h b/src/ripple_basics/ripple_basics.h
index ec70120b7a..71c132d655 100644
--- a/src/ripple_basics/ripple_basics.h
+++ b/src/ripple_basics/ripple_basics.h
@@ -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"
diff --git a/src/ripple_basics/types/ripple_BasicTypes.h b/src/ripple_basics/types/ripple_BasicTypes.h
index 2574c4e804..a845bc8c18 100644
--- a/src/ripple_basics/types/ripple_BasicTypes.h
+++ b/src/ripple_basics/types/ripple_BasicTypes.h
@@ -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
diff --git a/src/ripple_basics/utility/ripple_Log.cpp b/src/ripple_basics/utility/ripple_Log.cpp
deleted file mode 100644
index ab9a6053ca..0000000000
--- a/src/ripple_basics/utility/ripple_Log.cpp
+++ /dev/null
@@ -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 > 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;
-}
-
-//------------------------------------------------------------------------------
-
-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 ::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;
- }
- }
-}
-
diff --git a/src/ripple_basics/utility/ripple_Log.h b/src/ripple_basics/utility/ripple_Log.h
deleted file mode 100644
index 7ee8eb37e4..0000000000
--- a/src/ripple_basics/utility/ripple_Log.h
+++ /dev/null
@@ -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 ::Node
-{
-public:
- LogPartition (const char* partitionName);
-
- /** Retrieve the LogPartition associated with an object.
-
- Each LogPartition is a singleton.
- */
- template
- static LogPartition const& get ()
- {
- struct LogPartitionType : LogPartition
- {
- LogPartitionType () : LogPartition (getPartitionName ())
- {
- }
- };
-
- return *SharedSingleton ::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 > getSeverities ();
-
-private:
- /** Retrieve the name for a log partition.
- */
- template
- 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 () { return #Class; } \
- struct Class##Instantiator { Class##Instantiator () { LogPartition::get (); } }; \
- static Class##Instantiator Class##Instantiator_instance;
-
-#define SETUP_LOGN(Class,Name) \
- template <> char const* LogPartition::getPartitionName () { return Name; } \
- struct Class##Instantiator { Class##Instantiator () { LogPartition::get (); } }; \
- 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
- 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
- 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 ().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 ())
-
-// Write to the log conditionally
-//
-#define CondLog(c, s, k) if (!ShouldLog (s, k) || !(c)) do {} while(0); else Log(s, LogPartition::get ())
-
-#endif
diff --git a/src/ripple_data/protocol/ripple_RippleAddress.cpp b/src/ripple_data/protocol/ripple_RippleAddress.cpp
index 29249c2138..bb2f3e77c5 100644
--- a/src/ripple_data/protocol/ripple_RippleAddress.cpp
+++ b/src/ripple_data/protocol/ripple_RippleAddress.cpp
@@ -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;
diff --git a/src/ripple_data/protocol/ripple_RippleAddress.h b/src/ripple_data/protocol/ripple_RippleAddress.h
index cb05b20d13..56a5cb43d1 100644
--- a/src/ripple_data/protocol/ripple_RippleAddress.h
+++ b/src/ripple_data/protocol/ripple_RippleAddress.h
@@ -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
{