From d8707cad2ca513cdb5c6173a2319c608b7e234fa Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 15 Nov 2013 13:19:02 -0800 Subject: [PATCH] Refactor logging --- Builds/VisualStudio2012/RippleD.vcxproj | 7 - .../VisualStudio2012/RippleD.vcxproj.filters | 6 - src/BeastConfig.h | 19 -- src/ripple_app/main/Application.cpp | 27 +-- src/ripple_app/peers/Peers.cpp | 2 +- src/ripple_basics/log/Log.cpp | 33 +++- src/ripple_basics/log/Log.h | 58 ++---- src/ripple_basics/log/LogJournal.cpp | 107 ---------- src/ripple_basics/log/LogJournal.h | 72 ------- src/ripple_basics/log/LogPartition.cpp | 187 +++++++++++++++--- src/ripple_basics/log/LogPartition.h | 79 ++++++-- src/ripple_basics/log/LogSink.cpp | 9 +- src/ripple_basics/log/LogSink.h | 1 + src/ripple_basics/ripple_basics.cpp | 4 +- src/ripple_basics/ripple_basics.h | 1 - src/ripple_core/functional/Config.cpp | 3 + src/ripple_core/functional/Config.h | 1 + src/ripple_core/functional/ConfigSections.h | 1 + 18 files changed, 290 insertions(+), 327 deletions(-) delete mode 100644 src/ripple_basics/log/LogJournal.cpp delete mode 100644 src/ripple_basics/log/LogJournal.h diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 92d1b06a8..eb344603e 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -946,12 +946,6 @@ true true - - true - true - true - true - true true @@ -1911,7 +1905,6 @@ - diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index 97ede066d..2c7f9acbf 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -834,9 +834,6 @@ [2] Old Ripple\ripple_basics\log - - [2] Old Ripple\ripple_basics\log - [2] Old Ripple\ripple_basics\log @@ -1854,9 +1851,6 @@ [2] Old Ripple\ripple_basics\log - - [2] Old Ripple\ripple_basics\log - [2] Old Ripple\ripple_basics\log diff --git a/src/BeastConfig.h b/src/BeastConfig.h index 2b97cb4e3..7c6fd1920 100644 --- a/src/BeastConfig.h +++ b/src/BeastConfig.h @@ -154,25 +154,6 @@ #define RIPPLE_TRACK_MUTEXES 0 #endif -/** Config: RIPPLE_JOURNAL_MSVC_OUTPUT - A comma separated string of Journal partition names. The partitions which - appear in this list will be logged to the MSVC Output Window if the - process is launched from the IDE. -*/ -#ifndef RIPPLE_JOURNAL_MSVC_OUTPUT -#define RIPPLE_JOURNAL_MSVC_OUTPUT "" -#endif - -/** Config: RIPPLE_JOURNAL_MSVC_OUTPUT_SEVERITY - A Journal severity constant. Log entries below this severity that would be - destined for the MSVC Output Window will not be reported. This has no - effect on partitions not listed in RIPPLE_MSVC_OUTPUT_JOURNALS, or if not - running under the MSVC IDE. -*/ -#ifndef RIPPLE_JOURNAL_MSVC_OUTPUT_SEVERITY -#define RIPPLE_JOURNAL_MSVC_OUTPUT_SEVERITY Journal::kLowestSeverity -#endif - //------------------------------------------------------------------------------ // Here temporarily to turn off new Validations code while it diff --git a/src/ripple_app/main/Application.cpp b/src/ripple_app/main/Application.cpp index 813223b65..5b15a7ccd 100644 --- a/src/ripple_app/main/Application.cpp +++ b/src/ripple_app/main/Application.cpp @@ -26,7 +26,7 @@ static bool volatile doShutdown = false; // Specializations for LogPartition names // VFALCO NOTE This is temporary, until I refactor LogPartition -// and LogJournal::get() to take a string +// and LogPartition::getJournal() to take a string // class ApplicationLog; template <> char const* LogPartition::getPartitionName () { return "Application"; } @@ -71,20 +71,20 @@ public: ApplicationImp () : RootStoppable ("Application") - , m_journal (LogJournal::get ()) + , m_journal (LogPartition::getJournal ()) , m_tempNodeCache ("NodeCache", 16384, 90) , m_sleCache ("LedgerEntryCache", 4096, 120) , m_resourceManager (add (Resource::Manager::New ( - LogJournal::get ()))) + LogPartition::getJournal ()))) , m_rpcServiceManager (RPC::Manager::New ( - LogJournal::get ())) + LogPartition::getJournal ())) // The JobQueue has to come pretty early since // almost everything is a Stoppable child of the JobQueue. // - , m_jobQueue (JobQueue::New (*this, LogJournal::get ())) + , m_jobQueue (JobQueue::New (*this, LogPartition::getJournal ())) // The io_service must be a child of the JobQueue since we call addJob // in response to newtwork data from peers and also client requests. @@ -96,7 +96,7 @@ public: // , m_siteFiles (SiteFiles::Manager::New ( - *this, LogJournal::get ())) + *this, LogPartition::getJournal ())) , m_orderBookDB (*m_jobQueue) @@ -104,13 +104,13 @@ public: // VFALCO NOTE Does NetworkOPs depend on LedgerMaster? , m_networkOPs (NetworkOPs::New ( - m_ledgerMaster, *m_jobQueue, LogJournal::get ())) + m_ledgerMaster, *m_jobQueue, LogPartition::getJournal ())) // VFALCO NOTE LocalCredentials starts the deprecated UNL service , m_deprecatedUNL (UniqueNodeList::New (*m_jobQueue)) , m_rpcHTTPServer (RPCHTTPServer::New (*m_networkOPs, - LogJournal::get (), *m_jobQueue, *m_networkOPs, *m_resourceManager)) + LogPartition::getJournal (), *m_jobQueue, *m_networkOPs, *m_resourceManager)) #if ! RIPPLE_USE_RPC_SERVICE_MANAGER , m_rpcServerHandler (*m_networkOPs, *m_resourceManager) // passive object, not a Service @@ -128,13 +128,13 @@ public: , m_txQueue (TxQueue::New ()) , m_validators (add (Validators::Manager::New ( - *this, LogJournal::get ()))) + *this, LogPartition::getJournal ()))) , mFeatures (IFeatures::New (2 * 7 * 24 * 60 * 60, 200)) // two weeks, 200/256 , mFeeVote (IFeeVote::New (10, 50 * SYSTEM_CURRENCY_PARTS, 12.5 * SYSTEM_CURRENCY_PARTS)) - , mFeeTrack (LoadFeeTrack::New (LogJournal::get ())) + , mFeeTrack (LoadFeeTrack::New (LogPartition::getJournal ())) , mHashRouter (IHashRouter::New (IHashRouter::getDefaultHoldTime ())) @@ -142,7 +142,7 @@ public: , mProofOfWorkFactory (ProofOfWorkFactory::New ()) - , m_loadManager (LoadManager::New (*this, LogJournal::get ())) + , m_loadManager (LoadManager::New (*this, LogPartition::getJournal ())) , m_sweepTimer (this) @@ -396,6 +396,11 @@ public: LogPartition::setSeverity (lsDEBUG); } + if (!getConfig().CONSOLE_LOG_OUTPUT.empty()) + { + LogPartition::setConsoleOutput (getConfig().CONSOLE_LOG_OUTPUT); + } + if (!getConfig ().RUN_STANDALONE) m_sntpClient->init (getConfig ().SNTP_SERVERS); diff --git a/src/ripple_app/peers/Peers.cpp b/src/ripple_app/peers/Peers.cpp index cb6ff9406..3a071fcbd 100644 --- a/src/ripple_app/peers/Peers.cpp +++ b/src/ripple_app/peers/Peers.cpp @@ -99,7 +99,7 @@ public: *this, siteFiles, *this, - LogJournal::get ()))) + LogPartition::getJournal ()))) , m_io_service (io_service) , m_ssl_context (ssl_context) , mPeerLock (this, "PeersImp", __FILE__, __LINE__) diff --git a/src/ripple_basics/log/Log.cpp b/src/ripple_basics/log/Log.cpp index c8452c15f..fba8c493e 100644 --- a/src/ripple_basics/log/Log.cpp +++ b/src/ripple_basics/log/Log.cpp @@ -17,6 +17,33 @@ */ //============================================================================== +Log::Log (LogSeverity s) + : m_level (s) + , m_partition (nullptr) +{ +} + +Log::Log (LogSeverity s, LogPartition& partition) + : m_level (s) + , m_partition (&partition) +{ +} + +Log::~Log () +{ + if (m_partition != nullptr) + { + if (m_partition->doLog (m_level)) + m_partition->write ( + LogPartition::convertLogSeverity (m_level), m_os.str()); + } + else + { + LogSink::get()->write (m_os.str(), m_level, ""); + } +} + +//------------------------------------------------------------------------------ std::string Log::replaceFirstSecretWithAsterisks (std::string s) { @@ -47,11 +74,6 @@ std::string Log::replaceFirstSecretWithAsterisks (std::string s) //------------------------------------------------------------------------------ -Log::~Log () -{ - LogSink::get()->write (oss.str(), mSeverity, mPartitionName); -} - std::string Log::severityToString (LogSeverity s) { switch (s) @@ -102,3 +124,4 @@ LogSeverity Log::stringToSeverity (const std::string& s) return lsINVALID; } + diff --git a/src/ripple_basics/log/Log.h b/src/ripple_basics/log/Log.h index 0db1fd0bd..0bf481bf4 100644 --- a/src/ripple_basics/log/Log.h +++ b/src/ripple_basics/log/Log.h @@ -20,72 +20,38 @@ #ifndef RIPPLE_BASICS_LOG_H_INCLUDED #define RIPPLE_BASICS_LOG_H_INCLUDED -// A RAII helper for writing to the LogSink -// +/** 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 ()) - { - } - + explicit Log (LogSeverity s); + Log (LogSeverity s, LogPartition& partition); ~Log (); template std::ostream& operator<< (const T& t) const { - return oss << t; + return m_os << t; } std::ostringstream& ref () const { - return oss; + return m_os; } 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. - */ + // VFALCO DEPRECATED class out { public: - out () - { - } - - ~out () - { - LogSink::get()->write (m_ss.str ()); - } - + out () { } + ~out () { LogSink::get()->write (m_ss.str ()); } template out& operator<< (T t) - { - m_ss << t; - return *this; - } - + { m_ss << t; return *this; } private: std::stringstream m_ss; }; @@ -93,9 +59,9 @@ public: private: static std::string replaceFirstSecretWithAsterisks (std::string s); - mutable std::ostringstream oss; - LogSeverity mSeverity; - std::string mPartitionName; + mutable std::ostringstream m_os; + LogSeverity m_level; + LogPartition* m_partition; }; // Manually test for whether we should log diff --git a/src/ripple_basics/log/LogJournal.cpp b/src/ripple_basics/log/LogJournal.cpp deleted file mode 100644 index ac20f086c..000000000 --- a/src/ripple_basics/log/LogJournal.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -LogJournal::PartitionSinkBase::PartitionSinkBase (LogPartition& partition) - : m_partition (partition) - , m_severity (Journal::kLowestSeverity) - , m_to_console (false) -{ -#ifdef RIPPLE_JOURNAL_MSVC_OUTPUT - std::string const& list (RIPPLE_JOURNAL_MSVC_OUTPUT); - - std::string::const_iterator first (list.begin()); - for(;;) - { - std::string::const_iterator last (std::find ( - first, list.end(), ',')); - - if (std::equal (first, last, m_partition.getName().begin())) - { - set_console (true); - #ifdef RIPPLE_JOURNAL_MSVC_OUTPUT_SEVERITY - set_severity (RIPPLE_JOURNAL_MSVC_OUTPUT_SEVERITY); - #endif - break; - } - - if (last != list.end()) - first = last + 1; - else - break; - } -#endif -} - -void LogJournal::PartitionSinkBase::write ( - Journal::Severity severity, std::string const& text) -{ - std::string output; - LogSeverity const logSeverity (convertSeverity (severity)); - LogSink::get()->format (output, text, logSeverity, - m_partition.getName()); - LogSink::get()->write (output, logSeverity); -#if BEAST_MSVC - if (m_to_console && beast_isRunningUnderDebugger ()) - Logger::outputDebugString (output.c_str()); -#endif -} - -bool LogJournal::PartitionSinkBase::active ( - Journal::Severity severity) -{ - return m_partition.doLog (convertSeverity (severity)); -} - -bool LogJournal::PartitionSinkBase::console() -{ - return m_to_console; -} - -void LogJournal::PartitionSinkBase::set_severity ( - Journal::Severity severity) -{ - LogSeverity const logSeverity (convertSeverity (severity)); - m_partition.setMinimumSeverity (logSeverity); -} - -void LogJournal::PartitionSinkBase::set_console (bool to_console) -{ - m_to_console = to_console; -} - -//------------------------------------------------------------------------------ - -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 deleted file mode 100644 index 75b554850..000000000 --- a/src/ripple_basics/log/LogJournal.h +++ /dev/null @@ -1,72 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#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. */ - /** @{ */ - class PartitionSinkBase : public Journal::Sink - { - public: - explicit PartitionSinkBase (LogPartition& partition); - void write (Journal::Severity severity, std::string const& text); - bool active (Journal::Severity severity); - bool console(); - void set_severity (Journal::Severity severity); - void set_console (bool to_console); - - private: - LogPartition& m_partition; - Journal::Severity m_severity; - bool m_to_console; - }; - - template - class PartitionSink : public PartitionSinkBase - { - public: - PartitionSink () - : PartitionSinkBase (LogPartition::get ()) - { - } - }; - /** @} */ - - //-------------------------------------------------------------------------- - - /** 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 index 7a67d13fb..ab0d7dd0f 100644 --- a/src/ripple_basics/log/LogPartition.cpp +++ b/src/ripple_basics/log/LogPartition.cpp @@ -17,55 +17,182 @@ */ //============================================================================== - -LogPartition* LogPartition::headLog = NULL; - -LogPartition::LogPartition (char const* partitionName) - : mNextLog (headLog) - , mMinSeverity (lsWARNING) +bool LogPartition::active (Journal::Severity severity) const { - 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; + return convertSeverity (severity) >= mMinSeverity; } -std::vector< std::pair > LogPartition::getSeverities () +bool LogPartition::console () const { - std::vector< std::pair > sevs; + return m_console; +} - for (LogPartition* l = headLog; l != NULL; l = l->mNextLog) - sevs.push_back (std::make_pair (l->mName, Log::severityToString (l->mMinSeverity))); +void LogPartition::console (bool output) +{ + m_console = output; +} - return sevs; +Journal::Severity LogPartition::severity() const +{ + return convertLogSeverity (mMinSeverity); +} + +void LogPartition::severity (Journal::Severity level) +{ + setMinimumSeverity (convertSeverity (level)); +} + +void LogPartition::write (Journal::Severity level, std::string const& text) +{ + std::string output; + LogSeverity const logSeverity (convertSeverity (level)); + LogSink::get()->format (output, text, logSeverity, mName); + LogSink::get()->write (output, logSeverity); + if (m_console) + LogSink::get()->write_console (output); } //------------------------------------------------------------------------------ +LogPartition::LogPartition (std::string const& name) + : mNextLog (headLog) + , mMinSeverity (lsWARNING) + , mName (canonicalFileName (name.c_str())) + , m_console (false) +{ + // VFALCO TODO Use an intrusive list. + headLog = this; +} + +bool LogPartition::doLog (LogSeverity s) const +{ + return s >= mMinSeverity; +} + +std::string const& LogPartition::getName () const +{ + return mName; +} + +LogSeverity LogPartition::getSeverity() const +{ + return mMinSeverity; +} + void LogPartition::setMinimumSeverity (LogSeverity severity) { mMinSeverity = severity; } -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; +LogPartition* LogPartition::headLog = nullptr; + +std::string LogPartition::canonicalFileName (char const* fileName) +{ + std::string result; + char const* ptr (strrchr (fileName, '/')); + result = (ptr == nullptr) ? fileName : (ptr + 1); + + size_t p = result.find (".cpp"); + + if (p != std::string::npos) + result.erase (result.begin () + p, result.end ()); + + return result; +} + +LogPartition* LogPartition::find (std::string const& name) +{ + for (LogPartition* p = headLog; p != nullptr; p = p->mNextLog) + if (boost::iequals (p->getName(), name)) + return p; + return nullptr; } void LogPartition::setSeverity (LogSeverity severity) { - for (LogPartition* p = headLog; p != NULL; p = p->mNextLog) + for (LogPartition* p = headLog; p != nullptr; p = p->mNextLog) p->mMinSeverity = severity; } + +bool LogPartition::setSeverity (const std::string& partition, LogSeverity severity) +{ + LogPartition* const p (find (partition)); + + if (p) + { + p->mMinSeverity = severity; + return true; + } + + return false; +} + +void LogPartition::setConsoleOutput (std::string const& list) +{ + std::string::const_iterator first (list.begin()); + for(;;) + { + std::string::const_iterator last (std::find ( + first, list.end(), ',')); + + LogPartition* const p (find (std::string (first, last))); + if (p != nullptr) + p->console (true); + + if (last != list.end()) + first = last + 1; + else + break; + } +} + +LogPartition::Severities LogPartition::getSeverities () +{ + LogPartition::Severities result; + + for (LogPartition* l = headLog; l != nullptr; l = l->mNextLog) + result.push_back (std::make_pair (l->mName, Log::severityToString (l->mMinSeverity))); + + return result; +} + +//------------------------------------------------------------------------------ + +LogSeverity LogPartition::convertSeverity (Journal::Severity level) +{ + switch (level) + { + 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; +} + +Journal::Severity LogPartition::convertLogSeverity (LogSeverity level) +{ + switch (level) + { + case lsTRACE: return Journal::kTrace; + case lsDEBUG: return Journal::kDebug; + case lsINFO: return Journal::kInfo; + case lsWARNING: return Journal::kWarning; + case lsERROR: return Journal::kError; + default: + bassertfalse; + case lsFATAL: + break; + } + + return Journal::kFatal; +} diff --git a/src/ripple_basics/log/LogPartition.h b/src/ripple_basics/log/LogPartition.h index fbc83c52b..ea7cfca98 100644 --- a/src/ripple_basics/log/LogPartition.h +++ b/src/ripple_basics/log/LogPartition.h @@ -20,47 +20,89 @@ #ifndef RIPPLE_BASICS_LOGPARTITION_H_INCLUDED #define RIPPLE_BASICS_LOGPARTITION_H_INCLUDED -class LogPartition +class LogPartition : public Journal::Sink { public: - explicit LogPartition (const char* partitionName); + //-------------------------------------------------------------------------- + // + // Journal::Sink + // + //-------------------------------------------------------------------------- - /** Retrieve the LogPartition associated with an object. + bool active (Journal::Severity severity) const; + bool console () const; + void console (bool output); + Journal::Severity severity() const; + void severity (Journal::Severity level); + void write (Journal::Severity level, std::string const& text); - Each LogPartition is a singleton. - */ + //-------------------------------------------------------------------------- + + /** Construct the partition with the specified name. */ + explicit LogPartition (std::string const& name); + + /** Returns `true` output is produced at the given severity. */ + bool doLog (LogSeverity s) const; + + /** Returns the name of this partition. */ + std::string const& getName () const; + + /** Return the lowest severity reported on the partition. */ + LogSeverity getSeverity() const; + + /** Sets the lowest severity reported on the partition. */ + void setMinimumSeverity (LogSeverity severity); + + //-------------------------------------------------------------------------- + + /** Returns the LogPartition based on a type key. */ template static LogPartition& get () { struct LogPartitionType : LogPartition { LogPartitionType () : LogPartition (getPartitionName ()) - { - } + { } }; + // Each LogPartition is a singleton. return *SharedSingleton ::getInstance(); } - bool doLog (LogSeverity s) const + /** Returns a Journal using the specified LogPartition type key. */ + template + static Journal getJournal () { - return s >= mMinSeverity; + return Journal (get ()); } - const std::string& getName () const - { - return mName; - } + /** Returns a cleaned up source code file name. */ + static std::string canonicalFileName (char const* fileName); - void setMinimumSeverity (LogSeverity severity); + /** Returns the partition with the given name or nullptr if no match. */ + static LogPartition* find (std::string const& name); - static bool setSeverity (const std::string& partition, LogSeverity severity); + /** Set the minimum severity of all existing partitions at once. */ static void setSeverity (LogSeverity severity); - static std::vector< std::pair > getSeverities (); + + /** Set the minimum severity of a partition by name. */ + static bool setSeverity (std::string const& name, LogSeverity severity); + + /** Activate console output for the specified comma-separated partition list. */ + static void setConsoleOutput (std::string const& list); + + /** Returns a list of all partitions and their severity levels. */ + typedef std::vector > Severities; + static Severities getSeverities (); + + /** Convert the Journal::Severity to and from a LogSeverity. */ + /** @{ */ + static LogSeverity convertSeverity (Journal::Severity level); + static Journal::Severity convertLogSeverity (LogSeverity level); + /** @} */ private: - /** Retrieve the name for a log partition. - */ + /** Retrieve the name for a log partition. */ template static char const* getPartitionName (); @@ -72,6 +114,7 @@ private: LogPartition* mNextLog; LogSeverity mMinSeverity; std::string mName; + bool m_console; }; #define SETUP_LOG(Class) \ diff --git a/src/ripple_basics/log/LogSink.cpp b/src/ripple_basics/log/LogSink.cpp index dabb694b2..76c347069 100644 --- a/src/ripple_basics/log/LogSink.cpp +++ b/src/ripple_basics/log/LogSink.cpp @@ -128,7 +128,6 @@ void LogSink::write (std::string const& output, LogSeverity severity) void LogSink::write (std::string const& text) { ScopedLockType lock (m_mutex, __FILE__, __LINE__); - write (text, true, lock); } @@ -141,6 +140,14 @@ void LogSink::write (std::string const& line, bool toStdErr, ScopedLockType&) std::cerr << line << std::endl; } +void LogSink::write_console (std::string const& text) +{ +#if BEAST_MSVC + if (beast_isRunningUnderDebugger ()) + Logger::outputDebugString (text.c_str()); +#endif +} + //------------------------------------------------------------------------------ std::string LogSink::replaceFirstSecretWithAsterisks (std::string s) diff --git a/src/ripple_basics/log/LogSink.h b/src/ripple_basics/log/LogSink.h index de60288f1..e06c05ba0 100644 --- a/src/ripple_basics/log/LogSink.h +++ b/src/ripple_basics/log/LogSink.h @@ -65,6 +65,7 @@ public: void write (std::string const& message, LogSeverity severity, std::string const& partitionName); void write (std::string const& text, LogSeverity severity); void write (std::string const& text); + void write_console (std::string const& text); /** @} */ /** Hides secret keys from log output. */ diff --git a/src/ripple_basics/ripple_basics.cpp b/src/ripple_basics/ripple_basics.cpp index 261c3fcaf..80e6761a0 100644 --- a/src/ripple_basics/ripple_basics.cpp +++ b/src/ripple_basics/ripple_basics.cpp @@ -44,15 +44,13 @@ //------------------------------------------------------------------------------ -namespace ripple -{ +namespace ripple { #include "containers/RangeSet.cpp" #include "containers/TaggedCache.cpp" #include "log/Log.cpp" #include "log/LogFile.cpp" -#include "log/LogJournal.cpp" #include "log/LogPartition.cpp" #include "log/LogSink.cpp" diff --git a/src/ripple_basics/ripple_basics.h b/src/ripple_basics/ripple_basics.h index c346e4b02..80827c5c7 100644 --- a/src/ripple_basics/ripple_basics.h +++ b/src/ripple_basics/ripple_basics.h @@ -68,7 +68,6 @@ using namespace beast; # include "log/LogSink.h" # include "log/LogPartition.h" # include "log/Log.h" -#include "log/LogJournal.h" #include "log/LoggedTimings.h" #include "utility/CountedObject.h" diff --git a/src/ripple_core/functional/Config.cpp b/src/ripple_core/functional/Config.cpp index b98ba1dee..3f1d7567a 100644 --- a/src/ripple_core/functional/Config.cpp +++ b/src/ripple_core/functional/Config.cpp @@ -540,6 +540,9 @@ void Config::load () if (SectionSingleB (secConfig, SECTION_DEBUG_LOGFILE, strTemp)) DEBUG_LOGFILE = strTemp; + + if (SectionSingleB (secConfig, SECTION_CONSOLE_LOG_OUTPUT, strTemp)) + CONSOLE_LOG_OUTPUT = strTemp; } } } diff --git a/src/ripple_core/functional/Config.h b/src/ripple_core/functional/Config.h index 047cb67f7..7c303e6c3 100644 --- a/src/ripple_core/functional/Config.h +++ b/src/ripple_core/functional/Config.h @@ -336,6 +336,7 @@ public: bool TESTNET; boost::filesystem::path DEBUG_LOGFILE; + std::string CONSOLE_LOG_OUTPUT; bool ELB_SUPPORT; // Support Amazon ELB diff --git a/src/ripple_core/functional/ConfigSections.h b/src/ripple_core/functional/ConfigSections.h index e1b0698a7..a77c28bbb 100644 --- a/src/ripple_core/functional/ConfigSections.h +++ b/src/ripple_core/functional/ConfigSections.h @@ -38,6 +38,7 @@ struct ConfigSection #define SECTION_CLUSTER_NODES "cluster_nodes" #define SECTION_DATABASE_PATH "database_path" #define SECTION_DEBUG_LOGFILE "debug_logfile" +#define SECTION_CONSOLE_LOG_OUTPUT "console_log_output" #define SECTION_ELB_SUPPORT "elb_support" #define SECTION_FEE_DEFAULT "fee_default" #define SECTION_FEE_NICKNAME_CREATE "fee_nickname_create"