mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-30 07:55:51 +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"))
|
if (vm.count ("debug"))
|
||||||
setDebugJournalSink (logs->get("Debug"));
|
{
|
||||||
|
setDebugLogSink (logs->makeSink (
|
||||||
|
"Debug", beast::severities::kTrace));
|
||||||
|
}
|
||||||
|
|
||||||
auto timeKeeper = make_TimeKeeper(
|
auto timeKeeper = make_TimeKeeper(
|
||||||
logs->journal("TimeKeeper"));
|
logs->journal("TimeKeeper"));
|
||||||
|
|||||||
@@ -249,18 +249,18 @@ private:
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Debug logging:
|
// Debug logging:
|
||||||
|
|
||||||
/** Returns the debug journal. The journal may drain to a null sink. */
|
/** Set the sink for the debug journal. */
|
||||||
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.
|
|
||||||
*/
|
|
||||||
void
|
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
|
} // ripple
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,14 @@
|
|||||||
#include <BeastConfig.h>
|
#include <BeastConfig.h>
|
||||||
#include <ripple/basics/chrono.h>
|
#include <ripple/basics/chrono.h>
|
||||||
#include <ripple/basics/Log.h>
|
#include <ripple/basics/Log.h>
|
||||||
|
#include <ripple/basics/contract.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace ripple {
|
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&
|
class DebugSink
|
||||||
debugJournal()
|
|
||||||
{
|
{
|
||||||
if (!debugJournal_)
|
private:
|
||||||
debugJournal_ = std::make_unique<beast::Journal>();
|
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
|
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
|
} // ripple
|
||||||
|
|||||||
@@ -176,8 +176,13 @@ public:
|
|||||||
public:
|
public:
|
||||||
/** Create a stream which produces no output. */
|
/** Create a stream which produces no output. */
|
||||||
Stream ()
|
Stream ()
|
||||||
: m_sink (getNullSink())
|
: m_sink (getNullSink())
|
||||||
, m_level (severities::kDisabled)
|
, m_level (severities::kDisabled)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Stream (Sink& sink)
|
||||||
|
: m_sink (sink)
|
||||||
|
, m_level (sink.threshold())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/** Create stream that writes at the given level.
|
/** Create stream that writes at the given level.
|
||||||
@@ -194,7 +199,7 @@ public:
|
|||||||
/** Construct or copy another Stream. */
|
/** Construct or copy another Stream. */
|
||||||
Stream (Stream const& other)
|
Stream (Stream const& other)
|
||||||
: Stream (other.m_sink, other.m_level)
|
: Stream (other.m_sink, other.m_level)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Stream& operator= (Stream const& other) = delete;
|
Stream& operator= (Stream const& other) = delete;
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ T rangeCheckedCast (C c)
|
|||||||
std::numeric_limits<C>::is_signed &&
|
std::numeric_limits<C>::is_signed &&
|
||||||
c < std::numeric_limits<T>::lowest ()))
|
c < std::numeric_limits<T>::lowest ()))
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().error()) << "rangeCheckedCast domain error:"
|
JLOG (debugLog()) << "rangeCheckedCast domain error:"
|
||||||
<< " value = " << c
|
<< " value = " << c
|
||||||
<< " min = " << std::numeric_limits<T>::lowest ()
|
<< " min = " << std::numeric_limits<T>::lowest ()
|
||||||
<< " max: " << std::numeric_limits<T>::max ();
|
<< " max: " << std::numeric_limits<T>::max ();
|
||||||
|
|||||||
@@ -915,7 +915,7 @@ amountFromJsonNoThrow (STAmount& result, Json::Value const& jvSource)
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().debug()) <<
|
JLOG (debugLog()) <<
|
||||||
"amountFromJsonNoThrow: caught: " << e.what ();
|
"amountFromJsonNoThrow: caught: " << e.what ();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ STArray::STArray (SerialIter& sit, SField const& f)
|
|||||||
|
|
||||||
if ((type == STI_OBJECT) && (field == 1))
|
if ((type == STI_OBJECT) && (field == 1))
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().warn()) <<
|
JLOG (debugLog()) <<
|
||||||
"Encountered array with end of object marker";
|
"Encountered array with end of object marker";
|
||||||
Throw<std::runtime_error> ("Illegal terminator in array");
|
Throw<std::runtime_error> ("Illegal terminator in array");
|
||||||
}
|
}
|
||||||
@@ -85,14 +85,14 @@ STArray::STArray (SerialIter& sit, SField const& f)
|
|||||||
|
|
||||||
if (fn.isInvalid ())
|
if (fn.isInvalid ())
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().trace()) <<
|
JLOG (debugLog()) <<
|
||||||
"Unknown field: " << type << "/" << field;
|
"Unknown field: " << type << "/" << field;
|
||||||
Throw<std::runtime_error> ("Unknown field");
|
Throw<std::runtime_error> ("Unknown field");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fn.fieldType != STI_OBJECT)
|
if (fn.fieldType != STI_OBJECT)
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().trace()) <<
|
JLOG (debugLog()) <<
|
||||||
"Array contains non-object";
|
"Array contains non-object";
|
||||||
Throw<std::runtime_error> ("Non-object in array");
|
Throw<std::runtime_error> ("Non-object in array");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ STUInt8::getText () const
|
|||||||
if (transResultInfo (static_cast<TER> (value_), token, human))
|
if (transResultInfo (static_cast<TER> (value_), token, human))
|
||||||
return human;
|
return human;
|
||||||
|
|
||||||
JLOG (debugJournal().warn())
|
JLOG (debugLog())
|
||||||
<< "Unknown result code in metadata: " << value_;
|
<< "Unknown result code in metadata: " << value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ STUInt8::getJson (int) const
|
|||||||
if (transResultInfo (static_cast<TER> (value_), token, human))
|
if (transResultInfo (static_cast<TER> (value_), token, human))
|
||||||
return token;
|
return token;
|
||||||
|
|
||||||
JLOG (debugJournal().warn())
|
JLOG (debugLog())
|
||||||
<< "Unknown result code in metadata: " << value_;
|
<< "Unknown result code in metadata: " << value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ void STLedgerEntry::setSLEType ()
|
|||||||
type_ = mFormat->getType ();
|
type_ = mFormat->getType ();
|
||||||
if (!setType (mFormat->elements))
|
if (!setType (mFormat->elements))
|
||||||
{
|
{
|
||||||
if (auto j = debugJournal().warn())
|
if (auto j = debugLog())
|
||||||
{
|
{
|
||||||
j << "Ledger entry not valid for type " << mFormat->getName ();
|
j << "Ledger entry not valid for type " << mFormat->getName ();
|
||||||
j << "Object: " << getJson (0);
|
j << "Object: " << getJson (0);
|
||||||
@@ -141,7 +141,7 @@ bool STLedgerEntry::thread (uint256 const& txID, std::uint32_t ledgerSeq,
|
|||||||
{
|
{
|
||||||
uint256 oldPrevTxID = getFieldH256 (sfPreviousTxnID);
|
uint256 oldPrevTxID = getFieldH256 (sfPreviousTxnID);
|
||||||
|
|
||||||
JLOG (debugJournal().trace())
|
JLOG (debugLog())
|
||||||
<< "Thread Tx:" << txID << " prev:" << oldPrevTxID;
|
<< "Thread Tx:" << txID << " prev:" << oldPrevTxID;
|
||||||
|
|
||||||
if (oldPrevTxID == txID)
|
if (oldPrevTxID == txID)
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ bool STObject::setType (const SOTemplate& type)
|
|||||||
{
|
{
|
||||||
if ((e->flags == SOE_DEFAULT) && iter->get().isDefault())
|
if ((e->flags == SOE_DEFAULT) && iter->get().isDefault())
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().warn())
|
JLOG (debugLog())
|
||||||
<< "setType(" << getFName().getName()
|
<< "setType(" << getFName().getName()
|
||||||
<< "): explicit default " << e->e_field.fieldName;
|
<< "): explicit default " << e->e_field.fieldName;
|
||||||
valid = false;
|
valid = false;
|
||||||
@@ -125,7 +125,7 @@ bool STObject::setType (const SOTemplate& type)
|
|||||||
{
|
{
|
||||||
if (e->flags == SOE_REQUIRED)
|
if (e->flags == SOE_REQUIRED)
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().warn())
|
JLOG (debugLog())
|
||||||
<< "setType(" << getFName().getName()
|
<< "setType(" << getFName().getName()
|
||||||
<< "): missing " << e->e_field.fieldName;
|
<< "): missing " << e->e_field.fieldName;
|
||||||
valid = false;
|
valid = false;
|
||||||
@@ -138,7 +138,7 @@ bool STObject::setType (const SOTemplate& type)
|
|||||||
// Anything left over in the object must be discardable
|
// Anything left over in the object must be discardable
|
||||||
if (! e->getFName().isDiscardable())
|
if (! e->getFName().isDiscardable())
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().warn())
|
JLOG (debugLog())
|
||||||
<< "setType(" << getFName().getName()
|
<< "setType(" << getFName().getName()
|
||||||
<< "): non-discardable leftover " << e->getFName().getName ();
|
<< "): non-discardable leftover " << e->getFName().getName ();
|
||||||
valid = false;
|
valid = false;
|
||||||
@@ -208,7 +208,7 @@ bool STObject::set (SerialIter& sit, int depth)
|
|||||||
|
|
||||||
if ((type == STI_ARRAY) && (field == 1))
|
if ((type == STI_ARRAY) && (field == 1))
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().warn())
|
JLOG (debugLog())
|
||||||
<< "Encountered object with end of array marker";
|
<< "Encountered object with end of array marker";
|
||||||
Throw<std::runtime_error> ("Illegal terminator in object");
|
Throw<std::runtime_error> ("Illegal terminator in object");
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ bool STObject::set (SerialIter& sit, int depth)
|
|||||||
|
|
||||||
if (fn.isInvalid ())
|
if (fn.isInvalid ())
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().warn())
|
JLOG (debugLog())
|
||||||
<< "Unknown field: field_type=" << type
|
<< "Unknown field: field_type=" << type
|
||||||
<< ", field_name=" << field;
|
<< ", field_name=" << field;
|
||||||
Throw<std::runtime_error> ("Unknown field");
|
Throw<std::runtime_error> ("Unknown field");
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ STPathSet::STPathSet (SerialIter& sit, SField const& name)
|
|||||||
{
|
{
|
||||||
if (path.empty ())
|
if (path.empty ())
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().info())
|
JLOG (debugLog())
|
||||||
<< "Empty path in pathset";
|
<< "Empty path in pathset";
|
||||||
Throw<std::runtime_error> ("empty path");
|
Throw<std::runtime_error> ("empty path");
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ STPathSet::STPathSet (SerialIter& sit, SField const& name)
|
|||||||
}
|
}
|
||||||
else if (iType & ~STPathElement::typeAll)
|
else if (iType & ~STPathElement::typeAll)
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().info())
|
JLOG (debugLog())
|
||||||
<< "Bad path element " << iType << " in pathset";
|
<< "Bad path element " << iType << " in pathset";
|
||||||
Throw<std::runtime_error> ("bad path element");
|
Throw<std::runtime_error> ("bad path element");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ STValidation::STValidation (SerialIter& sit, bool checkSignature)
|
|||||||
|
|
||||||
if (checkSignature && !isValid ())
|
if (checkSignature && !isValid ())
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().trace())
|
JLOG (debugLog())
|
||||||
<< "Invalid validation" << getJson (0);
|
<< "Invalid validation" << getJson (0);
|
||||||
Throw<std::runtime_error> ("Invalid validation");
|
Throw<std::runtime_error> ("Invalid validation");
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ bool STValidation::isValid (uint256 const& signingHash) const
|
|||||||
}
|
}
|
||||||
catch (std::exception const&)
|
catch (std::exception const&)
|
||||||
{
|
{
|
||||||
JLOG (debugJournal().info())
|
JLOG (debugLog())
|
||||||
<< "Exception validating validation";
|
<< "Exception validating validation";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ public:
|
|||||||
bool plainOnly)
|
bool plainOnly)
|
||||||
: mSecure (secureOnly)
|
: mSecure (secureOnly)
|
||||||
, mBuffer ((plainOnly || secureOnly) ? 0 : 4)
|
, mBuffer ((plainOnly || secureOnly) ? 0 : 4)
|
||||||
, j_ (ripple::debugJournal())
|
|
||||||
{
|
{
|
||||||
mSocket = std::make_unique<ssl_socket> (s, c);
|
mSocket = std::make_unique<ssl_socket> (s, c);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user