diff --git a/src/ripple/app/main/Main.cpp b/src/ripple/app/main/Main.cpp index 764748a0b..e56eb8b5e 100644 --- a/src/ripple/app/main/Main.cpp +++ b/src/ripple/app/main/Main.cpp @@ -465,7 +465,10 @@ int run (int argc, char** argv) } if (vm.count ("debug")) - setDebugJournalSink (logs->get("Debug")); + { + setDebugLogSink (logs->makeSink ( + "Debug", beast::severities::kTrace)); + } auto timeKeeper = make_TimeKeeper( logs->journal("TimeKeeper")); diff --git a/src/ripple/basics/Log.h b/src/ripple/basics/Log.h index 131ebe72e..683715f50 100644 --- a/src/ripple/basics/Log.h +++ b/src/ripple/basics/Log.h @@ -249,18 +249,18 @@ private: //------------------------------------------------------------------------------ // Debug logging: -/** Returns the debug journal. The journal may drain to a null sink. */ -beast::Journal const& -debugJournal(); - -/** Set the sink for the debug journal - - This operation is not thread safe and should only be called - from a controlled context, when no other threads are in a - call to debugJournal. -*/ +/** Set the sink for the debug journal. */ void -setDebugJournalSink(beast::Journal::Sink& sink); +setDebugLogSink( + std::unique_ptr sink); + +/** Returns a debug journal. + The journal may drain to a null sink, so its output + may never be seen. Never use it for critical + information. +*/ +beast::Journal::Stream +debugLog(); } // ripple diff --git a/src/ripple/basics/impl/Log.cpp b/src/ripple/basics/impl/Log.cpp index 13f8b9172..86e9a8652 100644 --- a/src/ripple/basics/impl/Log.cpp +++ b/src/ripple/basics/impl/Log.cpp @@ -20,10 +20,14 @@ #include #include #include +#include #include #include -#include #include +#include +#include +#include +#include namespace ripple { @@ -340,21 +344,66 @@ Logs::format (std::string& output, std::string const& message, } //------------------------------------------------------------------------------ -static std::unique_ptr debugJournal_; -beast::Journal const& -debugJournal() +class DebugSink { - if (!debugJournal_) - debugJournal_ = std::make_unique(); +private: + std::reference_wrapper sink_; + std::unique_ptr holder_; + std::mutex m_; - return *debugJournal_; +public: + DebugSink () + : sink_ (beast::Journal::getNullSink()) + { + } + + DebugSink (DebugSink const&) = delete; + DebugSink& operator=(DebugSink const&) = delete; + + DebugSink(DebugSink&&) = delete; + DebugSink& operator=(DebugSink&&) = delete; + + void + set(std::unique_ptr sink) + { + std::lock_guard _(m_); + + holder_ = std::move(sink); + + if (holder_) + sink_ = *holder_; + else + sink_ = beast::Journal::getNullSink(); + } + + beast::Journal::Sink& + get() + { + std::lock_guard _(m_); + return sink_.get(); + } +}; + +static +DebugSink& +debugSink() +{ + static DebugSink _; + return _; } void -setDebugJournalSink(beast::Journal::Sink& sink) +setDebugLogSink( + std::unique_ptr sink) { - debugJournal_ = std::make_unique(sink); + debugSink().set(std::move(sink)); +} + +beast::Journal::Stream +debugLog() +{ + return { debugSink().get() }; } } // ripple diff --git a/src/ripple/beast/utility/Journal.h b/src/ripple/beast/utility/Journal.h index 810daf923..1785315a6 100644 --- a/src/ripple/beast/utility/Journal.h +++ b/src/ripple/beast/utility/Journal.h @@ -176,8 +176,13 @@ public: public: /** Create a stream which produces no output. */ Stream () - : m_sink (getNullSink()) - , m_level (severities::kDisabled) + : m_sink (getNullSink()) + , m_level (severities::kDisabled) + { } + + Stream (Sink& sink) + : m_sink (sink) + , m_level (sink.threshold()) { } /** Create stream that writes at the given level. @@ -194,7 +199,7 @@ public: /** Construct or copy another Stream. */ Stream (Stream const& other) : Stream (other.m_sink, other.m_level) - { } + { } Stream& operator= (Stream const& other) = delete; diff --git a/src/ripple/core/SociDB.h b/src/ripple/core/SociDB.h index 9ab966737..b6871af2f 100644 --- a/src/ripple/core/SociDB.h +++ b/src/ripple/core/SociDB.h @@ -52,7 +52,7 @@ T rangeCheckedCast (C c) std::numeric_limits::is_signed && c < std::numeric_limits::lowest ())) { - JLOG (debugJournal().error()) << "rangeCheckedCast domain error:" + JLOG (debugLog()) << "rangeCheckedCast domain error:" << " value = " << c << " min = " << std::numeric_limits::lowest () << " max: " << std::numeric_limits::max (); diff --git a/src/ripple/protocol/impl/STAmount.cpp b/src/ripple/protocol/impl/STAmount.cpp index 906075dd9..40914ffd9 100644 --- a/src/ripple/protocol/impl/STAmount.cpp +++ b/src/ripple/protocol/impl/STAmount.cpp @@ -915,7 +915,7 @@ amountFromJsonNoThrow (STAmount& result, Json::Value const& jvSource) } catch (const std::exception& e) { - JLOG (debugJournal().debug()) << + JLOG (debugLog()) << "amountFromJsonNoThrow: caught: " << e.what (); } return false; diff --git a/src/ripple/protocol/impl/STArray.cpp b/src/ripple/protocol/impl/STArray.cpp index 1cf8df903..09e6a5342 100644 --- a/src/ripple/protocol/impl/STArray.cpp +++ b/src/ripple/protocol/impl/STArray.cpp @@ -76,7 +76,7 @@ STArray::STArray (SerialIter& sit, SField const& f) if ((type == STI_OBJECT) && (field == 1)) { - JLOG (debugJournal().warn()) << + JLOG (debugLog()) << "Encountered array with end of object marker"; Throw ("Illegal terminator in array"); } @@ -85,14 +85,14 @@ STArray::STArray (SerialIter& sit, SField const& f) if (fn.isInvalid ()) { - JLOG (debugJournal().trace()) << + JLOG (debugLog()) << "Unknown field: " << type << "/" << field; Throw ("Unknown field"); } if (fn.fieldType != STI_OBJECT) { - JLOG (debugJournal().trace()) << + JLOG (debugLog()) << "Array contains non-object"; Throw ("Non-object in array"); } diff --git a/src/ripple/protocol/impl/STInteger.cpp b/src/ripple/protocol/impl/STInteger.cpp index 19aea4331..122e07414 100644 --- a/src/ripple/protocol/impl/STInteger.cpp +++ b/src/ripple/protocol/impl/STInteger.cpp @@ -52,7 +52,7 @@ STUInt8::getText () const if (transResultInfo (static_cast (value_), token, human)) return human; - JLOG (debugJournal().warn()) + JLOG (debugLog()) << "Unknown result code in metadata: " << value_; } @@ -70,7 +70,7 @@ STUInt8::getJson (int) const if (transResultInfo (static_cast (value_), token, human)) return token; - JLOG (debugJournal().warn()) + JLOG (debugLog()) << "Unknown result code in metadata: " << value_; } diff --git a/src/ripple/protocol/impl/STLedgerEntry.cpp b/src/ripple/protocol/impl/STLedgerEntry.cpp index d4c618204..a1fe627f8 100644 --- a/src/ripple/protocol/impl/STLedgerEntry.cpp +++ b/src/ripple/protocol/impl/STLedgerEntry.cpp @@ -78,7 +78,7 @@ void STLedgerEntry::setSLEType () type_ = mFormat->getType (); if (!setType (mFormat->elements)) { - if (auto j = debugJournal().warn()) + if (auto j = debugLog()) { j << "Ledger entry not valid for type " << mFormat->getName (); j << "Object: " << getJson (0); @@ -141,7 +141,7 @@ bool STLedgerEntry::thread (uint256 const& txID, std::uint32_t ledgerSeq, { uint256 oldPrevTxID = getFieldH256 (sfPreviousTxnID); - JLOG (debugJournal().trace()) + JLOG (debugLog()) << "Thread Tx:" << txID << " prev:" << oldPrevTxID; if (oldPrevTxID == txID) diff --git a/src/ripple/protocol/impl/STObject.cpp b/src/ripple/protocol/impl/STObject.cpp index d17a641a1..7a6282174 100644 --- a/src/ripple/protocol/impl/STObject.cpp +++ b/src/ripple/protocol/impl/STObject.cpp @@ -113,7 +113,7 @@ bool STObject::setType (const SOTemplate& type) { if ((e->flags == SOE_DEFAULT) && iter->get().isDefault()) { - JLOG (debugJournal().warn()) + JLOG (debugLog()) << "setType(" << getFName().getName() << "): explicit default " << e->e_field.fieldName; valid = false; @@ -125,7 +125,7 @@ bool STObject::setType (const SOTemplate& type) { if (e->flags == SOE_REQUIRED) { - JLOG (debugJournal().warn()) + JLOG (debugLog()) << "setType(" << getFName().getName() << "): missing " << e->e_field.fieldName; valid = false; @@ -138,7 +138,7 @@ bool STObject::setType (const SOTemplate& type) // Anything left over in the object must be discardable if (! e->getFName().isDiscardable()) { - JLOG (debugJournal().warn()) + JLOG (debugLog()) << "setType(" << getFName().getName() << "): non-discardable leftover " << e->getFName().getName (); valid = false; @@ -208,7 +208,7 @@ bool STObject::set (SerialIter& sit, int depth) if ((type == STI_ARRAY) && (field == 1)) { - JLOG (debugJournal().warn()) + JLOG (debugLog()) << "Encountered object with end of array marker"; Throw ("Illegal terminator in object"); } @@ -221,7 +221,7 @@ bool STObject::set (SerialIter& sit, int depth) if (fn.isInvalid ()) { - JLOG (debugJournal().warn()) + JLOG (debugLog()) << "Unknown field: field_type=" << type << ", field_name=" << field; Throw ("Unknown field"); diff --git a/src/ripple/protocol/impl/STPathSet.cpp b/src/ripple/protocol/impl/STPathSet.cpp index 126fb04f6..99e5962e3 100644 --- a/src/ripple/protocol/impl/STPathSet.cpp +++ b/src/ripple/protocol/impl/STPathSet.cpp @@ -64,7 +64,7 @@ STPathSet::STPathSet (SerialIter& sit, SField const& name) { if (path.empty ()) { - JLOG (debugJournal().info()) + JLOG (debugLog()) << "Empty path in pathset"; Throw ("empty path"); } @@ -77,7 +77,7 @@ STPathSet::STPathSet (SerialIter& sit, SField const& name) } else if (iType & ~STPathElement::typeAll) { - JLOG (debugJournal().info()) + JLOG (debugLog()) << "Bad path element " << iType << " in pathset"; Throw ("bad path element"); } diff --git a/src/ripple/protocol/impl/STValidation.cpp b/src/ripple/protocol/impl/STValidation.cpp index 24654c967..946792d6f 100644 --- a/src/ripple/protocol/impl/STValidation.cpp +++ b/src/ripple/protocol/impl/STValidation.cpp @@ -35,7 +35,7 @@ STValidation::STValidation (SerialIter& sit, bool checkSignature) if (checkSignature && !isValid ()) { - JLOG (debugJournal().trace()) + JLOG (debugLog()) << "Invalid validation" << getJson (0); Throw ("Invalid validation"); } @@ -113,7 +113,7 @@ bool STValidation::isValid (uint256 const& signingHash) const } catch (std::exception const&) { - JLOG (debugJournal().info()) + JLOG (debugLog()) << "Exception validating validation"; return false; } diff --git a/src/ripple/websocket/AutoSocket.h b/src/ripple/websocket/AutoSocket.h index 3317fdbe0..d80af11e4 100644 --- a/src/ripple/websocket/AutoSocket.h +++ b/src/ripple/websocket/AutoSocket.h @@ -53,7 +53,6 @@ public: bool plainOnly) : mSecure (secureOnly) , mBuffer ((plainOnly || secureOnly) ? 0 : 4) - , j_ (ripple::debugJournal()) { mSocket = std::make_unique (s, c); }