mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-30 16:05:51 +00:00
Journal console output improvements
This commit is contained in:
@@ -171,7 +171,7 @@
|
||||
// is being written.
|
||||
//
|
||||
#ifndef RIPPLE_USE_NEW_VALIDATORS
|
||||
#define RIPPLE_USE_NEW_VALIDATORS 0
|
||||
#define RIPPLE_USE_NEW_VALIDATORS 1
|
||||
#endif
|
||||
|
||||
// Turning this on makes the Application object get destroyed,
|
||||
|
||||
@@ -38,12 +38,15 @@ public:
|
||||
/** Severity level of the message. */
|
||||
enum Severity
|
||||
{
|
||||
kTrace,
|
||||
kLowestSeverity = 0,
|
||||
kTrace = kLowestSeverity,
|
||||
kDebug,
|
||||
kInfo,
|
||||
kWarning,
|
||||
kError,
|
||||
kFatal
|
||||
kFatal,
|
||||
|
||||
kDisabled
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -57,15 +60,16 @@ public:
|
||||
/** Write text to the sink at the specified severity. */
|
||||
virtual void write (Severity severity, std::string const& text) = 0;
|
||||
|
||||
/** Returns `true` if text at the passed severity produces output.
|
||||
The default implementation always returns `true`.
|
||||
*/
|
||||
virtual bool active (Severity);
|
||||
/** Returns `true` if text at the passed severity produces output. */
|
||||
virtual bool active (Severity severity) = 0;
|
||||
|
||||
/** Returns `true` if text at the severity goes to the Output window. */
|
||||
virtual bool console ();
|
||||
/** Returns `true` if a message is also written to the Output Window (MSVC). */
|
||||
virtual bool console () = 0;
|
||||
|
||||
/** Set the minimum severity this sink will report. */
|
||||
virtual void set_severity (Severity severity) = 0;
|
||||
|
||||
/** Set whether messages are also written to the Output Window (MSVC). */
|
||||
virtual void set_console (bool to_console) = 0;
|
||||
};
|
||||
|
||||
@@ -122,19 +126,26 @@ public:
|
||||
/** Construct a stream which produces no logging output. */
|
||||
Stream ();
|
||||
|
||||
/** Construct a stream that writes to the Sink at the given Severity. */
|
||||
Stream (Sink& sink, Severity severity);
|
||||
|
||||
/** Construct or copy another Stream. */
|
||||
/** @{ */
|
||||
Stream (Stream const& other);
|
||||
Stream& operator= (Stream const& other);
|
||||
/** @} */
|
||||
|
||||
/** Returns `true` if the sink logs messages at the severity of this stream. */
|
||||
bool active() const;
|
||||
|
||||
/** Returns `true` if the stream also logs messages to the Output window. */
|
||||
bool console() const;
|
||||
|
||||
/** Returns the Sink that this Stream writes to. */
|
||||
Sink& sink() const;
|
||||
|
||||
/** Returns the Severity of messages this Stream reports. */
|
||||
Severity severity() const;
|
||||
|
||||
/** Returns `true` if sink logs anything at this stream's severity. */
|
||||
bool active() const;
|
||||
|
||||
/** Output stream support. */
|
||||
/** @{ */
|
||||
ScopedStream operator<< (std::ostream& manip (std::ostream&)) const;
|
||||
|
||||
template <typename T>
|
||||
@@ -142,6 +153,7 @@ public:
|
||||
{
|
||||
return ScopedStream (*this, t);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
Sink* m_sink;
|
||||
@@ -155,16 +167,14 @@ public:
|
||||
Journal (Journal const& other);
|
||||
~Journal ();
|
||||
|
||||
/** Returns the Sink associated with this Journal. */
|
||||
Sink& sink() const;
|
||||
|
||||
/** Returns a stream for this sink, with the specified severity. */
|
||||
Stream stream (Severity severity) const;
|
||||
|
||||
Sink& sink() const;
|
||||
|
||||
/** Returns `true` if the sink logs messages at that severity. */
|
||||
/** @{ */
|
||||
/** Returns `true` if any message would be logged at this severity level. */
|
||||
bool active (Severity severity) const;
|
||||
bool console () const;
|
||||
/** @} */
|
||||
|
||||
/** Convenience sink streams for each severity level. */
|
||||
Stream const trace;
|
||||
|
||||
@@ -22,15 +22,7 @@
|
||||
namespace beast
|
||||
{
|
||||
|
||||
bool Journal::Sink::active (Severity)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Journal::Sink::console ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// A Sink that does nothing.
|
||||
class NullJournalSink : public Journal::Sink
|
||||
@@ -45,7 +37,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool console (Journal::Severity)
|
||||
bool console ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -94,11 +86,6 @@ Journal::ScopedStream::~ScopedStream ()
|
||||
{
|
||||
if (m_sink.active (m_severity))
|
||||
m_sink.write (m_severity, m_ostream.str());
|
||||
|
||||
#if BEAST_MSVC
|
||||
if (m_sink.console () && beast_isRunningUnderDebugger ())
|
||||
Logger::outputDebugString (m_ostream.str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +103,7 @@ std::ostringstream& Journal::ScopedStream::ostream () const
|
||||
|
||||
Journal::Stream::Stream ()
|
||||
: m_sink (&getNullSink ())
|
||||
, m_severity (kFatal)
|
||||
, m_severity (kDisabled)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -124,6 +111,7 @@ Journal::Stream::Stream (Sink& sink, Severity severity)
|
||||
: m_sink (&sink)
|
||||
, m_severity (severity)
|
||||
{
|
||||
bassert (severity != kDisabled);
|
||||
}
|
||||
|
||||
Journal::Stream::Stream (Stream const& other)
|
||||
@@ -132,16 +120,6 @@ Journal::Stream::Stream (Stream const& other)
|
||||
{
|
||||
}
|
||||
|
||||
bool Journal::Stream::active () const
|
||||
{
|
||||
return m_sink->active (m_severity);
|
||||
}
|
||||
|
||||
bool Journal::Stream::console() const
|
||||
{
|
||||
return m_sink->console ();
|
||||
}
|
||||
|
||||
Journal::Sink& Journal::Stream::sink () const
|
||||
{
|
||||
return *m_sink;
|
||||
@@ -152,6 +130,11 @@ Journal::Severity Journal::Stream::severity () const
|
||||
return m_severity;
|
||||
}
|
||||
|
||||
bool Journal::Stream::active () const
|
||||
{
|
||||
return m_sink->active (m_severity);
|
||||
}
|
||||
|
||||
Journal::Stream& Journal::Stream::operator= (Stream const& other)
|
||||
{
|
||||
m_sink = other.m_sink;
|
||||
@@ -203,25 +186,20 @@ Journal::~Journal ()
|
||||
{
|
||||
}
|
||||
|
||||
Journal::Stream Journal::stream (Severity severity) const
|
||||
{
|
||||
return Stream (*m_sink, severity);
|
||||
}
|
||||
|
||||
Journal::Sink& Journal::sink() const
|
||||
{
|
||||
return *m_sink;
|
||||
}
|
||||
|
||||
/** Returns `true` if the sink logs messages at that severity. */
|
||||
Journal::Stream Journal::stream (Severity severity) const
|
||||
{
|
||||
return Stream (*m_sink, severity);
|
||||
}
|
||||
|
||||
bool Journal::active (Severity severity) const
|
||||
{
|
||||
bassert (severity != kDisabled);
|
||||
return m_sink->active (severity);
|
||||
}
|
||||
|
||||
bool Journal::console () const
|
||||
{
|
||||
return m_sink->console ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#ifndef RIPPLE_VALIDATORS_MANAGER_H_INCLUDED
|
||||
#define RIPPLE_VALIDATORS_MANAGER_H_INCLUDED
|
||||
|
||||
@@ -25,56 +24,55 @@ namespace ripple {
|
||||
namespace Validators {
|
||||
|
||||
/** Maintains the list of chosen validators.
|
||||
|
||||
The algorithm for acquiring, building, and calculating metadata on
|
||||
the list of chosen validators is critical to the health of the network.
|
||||
|
||||
All operations are performed asynchronously on an internal thread.
|
||||
*/
|
||||
class Manager : public RPC::Service
|
||||
{
|
||||
public:
|
||||
/** Create a new Manager object.
|
||||
@param parent The parent Stoppable.
|
||||
@param journal Where to send log output.
|
||||
*/
|
||||
static Manager* New (Stoppable& parent, Journal journal);
|
||||
|
||||
/** Destroy the object.
|
||||
|
||||
Any pending source fetch operations are aborted.
|
||||
|
||||
There may be some listener calls made before the
|
||||
destructor returns.
|
||||
Any pending source fetch operations are aborted. This will block
|
||||
until any pending database I/O has completed and the thread has
|
||||
stopped.
|
||||
*/
|
||||
virtual ~Manager () { }
|
||||
|
||||
/** Add a static source of validators from a string array. */
|
||||
/** Add a static source of validators.
|
||||
The validators added using these methods will always be chosen when
|
||||
constructing the UNL regardless of statistics. The fetch operation
|
||||
is performed asynchronously, so this call returns immediately. A
|
||||
failed fetch (depending on the source) is not retried. The caller
|
||||
loses ownership of any dynamic objects.
|
||||
Thread safety:
|
||||
Can be called from any thread.
|
||||
*/
|
||||
/** @{ */
|
||||
virtual void addStrings (String name,
|
||||
std::vector <std::string> const& strings) = 0;
|
||||
virtual void addStrings (String name,
|
||||
StringArray const& stringArray) = 0;
|
||||
virtual void addFile (File const& file) = 0;
|
||||
virtual void addStaticSource (Source* source) = 0;
|
||||
/** @} */
|
||||
|
||||
/** Add a static source of validators from a text file. */
|
||||
virtual void addFile (File const& file) = 0;
|
||||
|
||||
/** Add a static source of validators.
|
||||
The Source is called to fetch once and the results are kept
|
||||
permanently. The fetch is performed asynchronously, this call
|
||||
returns immediately. If the fetch fails, it is not reattempted.
|
||||
The caller loses ownership of the object.
|
||||
/** Add a live source of validators from a trusted URL.
|
||||
The URL will be contacted periodically to update the list. The fetch
|
||||
operation is performed asynchronously, this call doesn't block.
|
||||
Thread safety:
|
||||
Can be called from any thread.
|
||||
*/
|
||||
virtual void addStaticSource (Source* source) = 0;
|
||||
|
||||
/** Add a live source of validators from a trusted URL.
|
||||
The URL will be contacted periodically to update the list.
|
||||
*/
|
||||
virtual void addURL (URL const& url) = 0;
|
||||
|
||||
/** Add a live source of validators.
|
||||
The caller loses ownership of the object.
|
||||
The caller loses ownership of the object. The fetch is performed
|
||||
asynchronously, this call doesn't block.
|
||||
Thread safety:
|
||||
Can be called from any thread.
|
||||
*/
|
||||
@@ -82,12 +80,8 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Trusted Validators
|
||||
|
||||
//virtual bool isPublicKeyTrusted (RipplePublicKey const& publicKey) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Called when a validation with a proper signature is received. */
|
||||
virtual void receiveValidation (ReceivedValidation const& rv) = 0;
|
||||
|
||||
|
||||
@@ -17,84 +17,82 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
/** ChosenValidators (formerly known as UNL)
|
||||
|
||||
Information to track:
|
||||
Motivation:
|
||||
|
||||
- Percentage of validations that the validator has signed
|
||||
- Number of validations the validator signed that never got accepted
|
||||
To protect the integrity of the shared ledger data structure, Validators
|
||||
independently sign LedgerHash objects with their RipplePublicKey. These
|
||||
signed Validations are propagated through the peer to peer network so
|
||||
that other nodes may inspect them. Every peer and client on the network
|
||||
gains confidence in a ledger and its associated chain of previous ledgers
|
||||
by maintaining a suitably sized list of Validator public keys that it
|
||||
trusts.
|
||||
|
||||
The most important factors in choosing Validators for a ChosenValidators
|
||||
list (the name we will use to designate such a list) are the following:
|
||||
|
||||
- That different Validators are not controlled by one entity
|
||||
- That each Validator participates in a majority of ledgers
|
||||
- That a Validator does not sign ledgers which fail consensus
|
||||
|
||||
This module maintains ChosenValidators list. The list is built from a set
|
||||
of independent Source objects, which may come from the configuration file,
|
||||
a separate file, a URL from some trusted domain, or from the network itself.
|
||||
|
||||
In order that rippled administrators may publish their ChosenValidators
|
||||
list at a URL on a trusted domain that they own, this module compiles
|
||||
statistics on ledgers signed by validators and stores them in a database.
|
||||
From this database reports and alerts may be generated so that up-to-date
|
||||
information about the health of the set of ChosenValidators is always
|
||||
availabile.
|
||||
|
||||
In addition to the automated statistics provided by the module, it is
|
||||
expected that organizations and meta-organizations will form from
|
||||
stakeholders such as gateways who publish their own lists and provide
|
||||
"best practices" to further refine the quality of validators placed into
|
||||
ChosenValidators list.
|
||||
|
||||
|
||||
- Target number for Chosen
|
||||
- Pseudo-randomly choose a subset from Chosen
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Unorganized Notes:
|
||||
|
||||
David:
|
||||
Maybe OC should have a URL that you can query to get the latest list of URI's
|
||||
for OC-approved organzations that publish lists of validators. The server and
|
||||
client can ship with that master trust URL and also the list of URI's at the
|
||||
time it's released, in case for some reason it can't pull from OC. That would
|
||||
make the default installation safe even against major changes in the
|
||||
organizations that publish validator lists.
|
||||
|
||||
The difference is that if an organization that provides lists of validators
|
||||
goes rogue, administrators don't have to act.
|
||||
|
||||
TODO:
|
||||
Write up from end-user perspective on the deployment and administration
|
||||
of this feature, on the wiki. "DRAFT" or "PROPOSE" to mark it as provisional.
|
||||
Template: https://ripple.com/wiki/Federation_protocol
|
||||
- What to do if you're a publisher of ValidatorList
|
||||
- What to do if you're a rippled administrator
|
||||
- Overview of how ChosenValidators works
|
||||
|
||||
Goal:
|
||||
Goals:
|
||||
Make default configuration of rippled secure.
|
||||
* Ship with TrustedUriList
|
||||
* Also have a preset RankedValidators
|
||||
Eliminate administrative burden of maintaining
|
||||
Produce the ChosenValidators list.
|
||||
Allow quantitative analysis of network health.
|
||||
|
||||
Provide the listener with a ValidatorList.
|
||||
- This forms the UNL
|
||||
|
||||
Task:
|
||||
|
||||
fetch ValidatorInfo array from a source
|
||||
|
||||
- We have the old one and the new one, compute the following:
|
||||
|
||||
* unchanged validators list
|
||||
* new validators list
|
||||
* removed validators list
|
||||
|
||||
- From the unchanged / new / removed, figure out what to do.
|
||||
|
||||
Two important questions:
|
||||
|
||||
- Are there any validators in my ChosenValidators that I dont want
|
||||
* For example, they have dropped off all the trusted lists
|
||||
|
||||
- Do I have enough?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ChosenValidators
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
David:
|
||||
Maybe OC should have a URL that you can query to get the latest list of URI's
|
||||
for OC-approved organzations that publish lists of validators. The server and
|
||||
client can ship with that master trust URL and also the list of URI's at the
|
||||
time it's released, in case for some reason it can't pull from OC. That would
|
||||
make the default installation safe even against major changes in the
|
||||
organizations that publish validator lists.
|
||||
|
||||
The difference is that if an organization that provides lists of validators
|
||||
goes rogue, administrators don't have to act.
|
||||
|
||||
TODO:
|
||||
Write up from end-user perspective on the deployment and administration
|
||||
of this feature, on the wiki. "DRAFT" or "PROPOSE" to mark it as provisional.
|
||||
Template: https://ripple.com/wiki/Federation_protocol
|
||||
- What to do if you're a publisher of ValidatorList
|
||||
- What to do if you're a rippled administrator
|
||||
- Overview of how ChosenValidators works
|
||||
|
||||
Goals:
|
||||
Make default configuration of rippled secure.
|
||||
* Ship with TrustedUriList
|
||||
* Also have a preset RankedValidators
|
||||
Eliminate administrative burden of maintaining
|
||||
Produce the ChosenValidators list.
|
||||
Allow quantitative analysis of network health.
|
||||
|
||||
What determines that a validator is good?
|
||||
- Are they present (i.e. sending validations)
|
||||
- Are they on the consensus ledger
|
||||
- What percentage of consensus rounds do they participate in
|
||||
- Are they stalling consensus
|
||||
* Measurements of constructive/destructive behavior is
|
||||
calculated in units of percentage of ledgers for which
|
||||
the behavior is measured.
|
||||
What determines that a validator is good?
|
||||
- Are they present (i.e. sending validations)
|
||||
- Are they on the consensus ledger
|
||||
- What percentage of consensus rounds do they participate in
|
||||
- Are they stalling consensus
|
||||
* Measurements of constructive/destructive behavior is
|
||||
calculated in units of percentage of ledgers for which
|
||||
the behavior is measured.
|
||||
*/
|
||||
|
||||
namespace ripple {
|
||||
@@ -128,7 +126,13 @@ public:
|
||||
, m_checkTimer (this)
|
||||
, m_checkSources (true)
|
||||
{
|
||||
m_journal.sink().set_console (true);
|
||||
#if BEAST_MSVC
|
||||
if (beast_isRunningUnderDebugger())
|
||||
{
|
||||
m_journal.sink().set_console (true);
|
||||
m_journal.sink().set_severity (Journal::kLowestSeverity);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
~ManagerImp ()
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#ifndef RIPPLE_BASICS_LOGJOURNAL_H_INCLUDED
|
||||
#define RIPPLE_BASICS_LOGJOURNAL_H_INCLUDED
|
||||
|
||||
@@ -37,13 +36,22 @@ public:
|
||||
public:
|
||||
PartitionSink ()
|
||||
: m_partition (LogPartition::get <Key> ())
|
||||
, m_console (false)
|
||||
, m_severity (Journal::kLowestSeverity)
|
||||
, m_to_console (false)
|
||||
{
|
||||
}
|
||||
|
||||
void write (Journal::Severity severity, std::string const& text)
|
||||
{
|
||||
LogSink::get()->write (text, convertSeverity (severity), m_partition.getName());
|
||||
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 active (Journal::Severity severity)
|
||||
@@ -53,24 +61,24 @@ public:
|
||||
|
||||
bool console()
|
||||
{
|
||||
return m_console;
|
||||
return m_to_console;
|
||||
}
|
||||
|
||||
void set_severity (Journal::Severity severity)
|
||||
{
|
||||
// VFALCO TODO Per-partition severity levels
|
||||
bassertfalse;
|
||||
LogSeverity const logSeverity (convertSeverity (severity));
|
||||
m_partition.setMinimumSeverity (logSeverity);
|
||||
}
|
||||
|
||||
void set_console (bool to_console)
|
||||
{
|
||||
m_console = to_console;
|
||||
m_to_console = to_console;
|
||||
}
|
||||
|
||||
private:
|
||||
LogPartition const& m_partition;
|
||||
LogPartition& m_partition;
|
||||
Journal::Severity m_severity;
|
||||
bool m_console;
|
||||
bool m_to_console;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -47,6 +47,11 @@ std::vector< std::pair<std::string, std::string> > LogPartition::getSeverities (
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
|
||||
@@ -21,17 +21,17 @@
|
||||
#ifndef RIPPLE_BASICS_LOGPARTITION_H_INCLUDED
|
||||
#define RIPPLE_BASICS_LOGPARTITION_H_INCLUDED
|
||||
|
||||
class LogPartition // : public List <LogPartition>::Node
|
||||
class LogPartition
|
||||
{
|
||||
public:
|
||||
LogPartition (const char* partitionName);
|
||||
explicit LogPartition (const char* partitionName);
|
||||
|
||||
/** Retrieve the LogPartition associated with an object.
|
||||
|
||||
Each LogPartition is a singleton.
|
||||
*/
|
||||
template <class Key>
|
||||
static LogPartition const& get ()
|
||||
static LogPartition& get ()
|
||||
{
|
||||
struct LogPartitionType : LogPartition
|
||||
{
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
return mName;
|
||||
}
|
||||
|
||||
void setMinimumSeverity (LogSeverity severity);
|
||||
|
||||
static bool setSeverity (const std::string& partition, LogSeverity severity);
|
||||
static void setSeverity (LogSeverity severity);
|
||||
static std::vector< std::pair<std::string, std::string> > getSeverities ();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
LogSink::LogSink ()
|
||||
: m_mutex ("Log", __FILE__, __LINE__)
|
||||
, m_minSeverity (lsINFO)
|
||||
@@ -71,47 +70,59 @@ std::string LogSink::rotateLog ()
|
||||
}
|
||||
}
|
||||
|
||||
void LogSink::format (
|
||||
std::string& output,
|
||||
std::string const& message,
|
||||
LogSeverity severity,
|
||||
std::string const& partitionName)
|
||||
{
|
||||
output.reserve (message.size() + partitionName.size() + 100);
|
||||
|
||||
output = boost::posix_time::to_simple_string (
|
||||
boost::posix_time::second_clock::universal_time ());
|
||||
|
||||
output += " ";
|
||||
if (! partitionName.empty ())
|
||||
output += partitionName + ":";
|
||||
|
||||
switch (severity)
|
||||
{
|
||||
case lsTRACE: output += "TRC "; break;
|
||||
case lsDEBUG: output += "DBG "; break;
|
||||
case lsINFO: output += "NFO "; break;
|
||||
case lsWARNING: output += "WRN "; break;
|
||||
case lsERROR: output += "ERR "; break;
|
||||
default:
|
||||
bassertfalse;
|
||||
case lsFATAL: output += "FTL ";
|
||||
break;
|
||||
}
|
||||
|
||||
output += replaceFirstSecretWithAsterisks (message);
|
||||
|
||||
if (output.size() > maximumMessageCharacters)
|
||||
{
|
||||
output.resize (maximumMessageCharacters - 3);
|
||||
output += "...";
|
||||
}
|
||||
}
|
||||
|
||||
void LogSink::write (
|
||||
std::string const& message,
|
||||
LogSeverity severity,
|
||||
std::string const& partitionName)
|
||||
{
|
||||
std::string text;
|
||||
text.reserve (message.size() + partitionName.size() + 100);
|
||||
std::string output;
|
||||
|
||||
text = boost::posix_time::to_simple_string (
|
||||
boost::posix_time::second_clock::universal_time ());
|
||||
format (output, message, severity, partitionName);
|
||||
|
||||
text += " ";
|
||||
if (! partitionName.empty ())
|
||||
text += partitionName + ":";
|
||||
write (output, severity);
|
||||
}
|
||||
|
||||
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& output, LogSeverity severity)
|
||||
{
|
||||
ScopedLockType lock (m_mutex, __FILE__, __LINE__);
|
||||
write (output, severity >= getMinSeverity(), lock);
|
||||
}
|
||||
|
||||
void LogSink::write (std::string const& text)
|
||||
@@ -121,37 +132,13 @@ void LogSink::write (std::string const& text)
|
||||
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 0
|
||||
#if BEAST_MSVC
|
||||
if (beast_isRunningUnderDebugger ())
|
||||
{
|
||||
// Send it to the attached debugger's Output window
|
||||
//
|
||||
Logger::outputDebugString (line);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
std::cerr << line << std::endl;
|
||||
}
|
||||
}
|
||||
std::cerr << line << std::endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#ifndef RIPPLE_BASICS_LOGSINK_H_INCLUDED
|
||||
#define RIPPLE_BASICS_LOGSINK_H_INCLUDED
|
||||
|
||||
@@ -31,7 +30,10 @@ public:
|
||||
/** Returns the minimum severity required for also writing to stderr. */
|
||||
LogSeverity getMinSeverity ();
|
||||
|
||||
/** Sets the minimum severity required for also writing to stderr. */
|
||||
/** Sets the minimum severity required for also writing to stderr.
|
||||
If 'all' is true this will set the minimum reporting severity for
|
||||
all partitions.
|
||||
*/
|
||||
void setMinSeverity (LogSeverity, bool all);
|
||||
|
||||
/** Sets the path to the log file. */
|
||||
@@ -44,14 +46,14 @@ public:
|
||||
*/
|
||||
std::string rotateLog ();
|
||||
|
||||
/** Format a log message. */
|
||||
void format (std::string& output,
|
||||
std::string const& message, LogSeverity severity,
|
||||
std::string const& partitionName);
|
||||
|
||||
/** 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
|
||||
All logging eventually goes through these functios.
|
||||
The text should not contain a final newline, it will be automatically
|
||||
added as needed.
|
||||
|
||||
@note This acquires a global mutex.
|
||||
@@ -60,10 +62,9 @@ public:
|
||||
@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& message, LogSeverity severity, std::string const& partitionName);
|
||||
void write (std::string const& text, LogSeverity severity);
|
||||
void write (std::string const& text);
|
||||
void write (StringArray const& strings);
|
||||
/** @} */
|
||||
|
||||
/** Hides secret keys from log output. */
|
||||
|
||||
Reference in New Issue
Block a user