mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 22:45:52 +00:00
Serialize access to the debug journal
This commit is contained in:
@@ -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"));
|
||||
|
||||
@@ -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<beast::Journal::Sink> 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
|
||||
|
||||
|
||||
@@ -20,10 +20,14 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -340,21 +344,66 @@ Logs::format (std::string& output, std::string const& message,
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static std::unique_ptr<beast::Journal> debugJournal_;
|
||||
|
||||
beast::Journal const&
|
||||
debugJournal()
|
||||
class DebugSink
|
||||
{
|
||||
if (!debugJournal_)
|
||||
debugJournal_ = std::make_unique<beast::Journal>();
|
||||
private:
|
||||
std::reference_wrapper<beast::Journal::Sink> sink_;
|
||||
std::unique_ptr<beast::Journal::Sink> 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<beast::Journal::Sink> sink)
|
||||
{
|
||||
std::lock_guard<std::mutex> _(m_);
|
||||
|
||||
holder_ = std::move(sink);
|
||||
|
||||
if (holder_)
|
||||
sink_ = *holder_;
|
||||
else
|
||||
sink_ = beast::Journal::getNullSink();
|
||||
}
|
||||
|
||||
beast::Journal::Sink&
|
||||
get()
|
||||
{
|
||||
std::lock_guard<std::mutex> _(m_);
|
||||
return sink_.get();
|
||||
}
|
||||
};
|
||||
|
||||
static
|
||||
DebugSink&
|
||||
debugSink()
|
||||
{
|
||||
static DebugSink _;
|
||||
return _;
|
||||
}
|
||||
|
||||
void
|
||||
setDebugJournalSink(beast::Journal::Sink& sink)
|
||||
setDebugLogSink(
|
||||
std::unique_ptr<beast::Journal::Sink> sink)
|
||||
{
|
||||
debugJournal_ = std::make_unique<beast::Journal>(sink);
|
||||
debugSink().set(std::move(sink));
|
||||
}
|
||||
|
||||
beast::Journal::Stream
|
||||
debugLog()
|
||||
{
|
||||
return { debugSink().get() };
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ T rangeCheckedCast (C c)
|
||||
std::numeric_limits<C>::is_signed &&
|
||||
c < std::numeric_limits<T>::lowest ()))
|
||||
{
|
||||
JLOG (debugJournal().error()) << "rangeCheckedCast domain error:"
|
||||
JLOG (debugLog()) << "rangeCheckedCast domain error:"
|
||||
<< " value = " << c
|
||||
<< " min = " << std::numeric_limits<T>::lowest ()
|
||||
<< " max: " << std::numeric_limits<T>::max ();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<std::runtime_error> ("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<std::runtime_error> ("Unknown field");
|
||||
}
|
||||
|
||||
if (fn.fieldType != STI_OBJECT)
|
||||
{
|
||||
JLOG (debugJournal().trace()) <<
|
||||
JLOG (debugLog()) <<
|
||||
"Array contains non-object";
|
||||
Throw<std::runtime_error> ("Non-object in array");
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ STUInt8::getText () const
|
||||
if (transResultInfo (static_cast<TER> (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<TER> (value_), token, human))
|
||||
return token;
|
||||
|
||||
JLOG (debugJournal().warn())
|
||||
JLOG (debugLog())
|
||||
<< "Unknown result code in metadata: " << value_;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<std::runtime_error> ("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<std::runtime_error> ("Unknown field");
|
||||
|
||||
@@ -64,7 +64,7 @@ STPathSet::STPathSet (SerialIter& sit, SField const& name)
|
||||
{
|
||||
if (path.empty ())
|
||||
{
|
||||
JLOG (debugJournal().info())
|
||||
JLOG (debugLog())
|
||||
<< "Empty path in pathset";
|
||||
Throw<std::runtime_error> ("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<std::runtime_error> ("bad path element");
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ STValidation::STValidation (SerialIter& sit, bool checkSignature)
|
||||
|
||||
if (checkSignature && !isValid ())
|
||||
{
|
||||
JLOG (debugJournal().trace())
|
||||
JLOG (debugLog())
|
||||
<< "Invalid validation" << getJson (0);
|
||||
Throw<std::runtime_error> ("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;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ public:
|
||||
bool plainOnly)
|
||||
: mSecure (secureOnly)
|
||||
, mBuffer ((plainOnly || secureOnly) ? 0 : 4)
|
||||
, j_ (ripple::debugJournal())
|
||||
{
|
||||
mSocket = std::make_unique<ssl_socket> (s, c);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user