Improve JSON logging

This commit is contained in:
Brad Chase
2017-11-14 13:27:02 -05:00
committed by seelabs
parent c42ea14531
commit 3e483cfa4c
8 changed files with 169 additions and 100 deletions

View File

@@ -1020,8 +1020,9 @@ Consensus<Adaptor>::checkLedger()
<< ", "
<< " mode=" << to_string(mode_.get());
JLOG(j_.warn()) << prevLedgerID_ << " to " << netLgr;
JLOG(j_.warn()) << previousLedger_.getJson();
JLOG(j_.debug()) << "State on consensus change " << getJson(true);
JLOG(j_.warn()) << Json::Compact{previousLedger_.getJson()};
JLOG(j_.debug()) << "State on consensus change "
<< Json::Compact{getJson(true)};
handleWrongLedger(netLgr);
}
else if (previousLedger_.id() != prevLedgerID_)
@@ -1434,7 +1435,7 @@ Consensus<Adaptor>::haveConsensus()
if (result_->state == ConsensusState::MovedOn)
{
JLOG(j_.error()) << "Unable to reach consensus";
JLOG(j_.error()) << getJson(true);
JLOG(j_.error()) << Json::Compact{getJson(true)};
}
return true;

View File

@@ -25,6 +25,7 @@
#include <ripple/basics/base_uint.h>
#include <ripple/beast/utility/Journal.h>
#include <ripple/consensus/ConsensusParms.h>
#include <ripple/json/json_writer.h>
#include <ripple/protocol/Serializer.h>
#include <ripple/protocol/UintTypes.h>
#include <memory>
@@ -239,14 +240,14 @@ DisputedTx<Tx_t, NodeID_t>::updateVote(
JLOG(j_.info()) << "No change (" << (ourVote_ ? "YES" : "NO")
<< ") : weight " << weight << ", percent "
<< percentTime;
JLOG(j_.debug()) << getJson();
JLOG(j_.debug()) << Json::Compact{getJson()};
return false;
}
ourVote_ = newPosition;
JLOG(j_.debug()) << "We now vote " << (ourVote_ ? "YES" : "NO") << " on "
<< tx_.id();
JLOG(j_.debug()) << getJson();
JLOG(j_.debug()) << Json::Compact{getJson()};
return true;
}

View File

@@ -743,87 +743,4 @@ std::ostream& operator<< ( std::ostream& sout, const Value& root )
return sout;
}
//------------------------------------------------------------------------------
namespace detail {
inline
void
write_string (write_t write, std::string const& s)
{
write(s.data(), s.size());
}
void
write_value (write_t write, Value const& value)
{
switch (value.type())
{
case nullValue:
write("null", 4);
break;
case intValue:
write_string(write, valueToString(value.asInt()));
break;
case uintValue:
write_string(write, valueToString(value.asUInt()));
break;
case realValue:
write_string(write, valueToString(value.asDouble()));
break;
case stringValue:
write_string(write, valueToQuotedString(value.asCString()));
break;
case booleanValue:
write_string(write, valueToString(value.asBool()));
break;
case arrayValue:
{
write("[", 1);
int const size = value.size();
for (int index = 0; index < size; ++index)
{
if (index > 0)
write(",", 1);
write_value(write, value[index]);
}
write("]", 1);
break;
}
case objectValue:
{
Value::Members const members = value.getMemberNames();
write("{", 1);
for (auto it = members.begin(); it != members.end(); ++it)
{
std::string const& name = *it;
if (it != members.begin())
write(",", 1);
write_string(write, valueToQuotedString(name.c_str()));
write(":", 1);
write_value(write, value[name]);
}
write("}", 1);
break;
}
}
}
} // detail
void
stream (Json::Value const& jv, write_t write)
{
detail::write_value(write, jv);
write("\n", 1);
}
} // namespace Json

View File

@@ -606,14 +606,6 @@ public:
}
};
//------------------------------------------------------------------------------
using write_t = std::function<void(void const*, std::size_t)>;
/** Stream compact JSON to the specified function. */
void
stream (Json::Value const& jv, write_t write);
} // namespace Json

View File

@@ -22,6 +22,7 @@
#include <ripple/json/json_forwards.h>
#include <ripple/json/json_value.h>
#include <ostream>
#include <vector>
namespace Json
@@ -175,8 +176,137 @@ std::string valueToQuotedString ( const char* value );
/// \see Json::operator>>()
std::ostream& operator<< ( std::ostream&, const Value& root );
} // namespace Json
//------------------------------------------------------------------------------
// Helpers for stream
namespace detail {
template <class Write>
void
write_string(Write const& write, std::string const& s)
{
write(s.data(), s.size());
}
template <class Write>
void
write_value(Write const& write, Value const& value)
{
switch (value.type())
{
case nullValue:
write("null", 4);
break;
case intValue:
write_string(write, valueToString(value.asInt()));
break;
case uintValue:
write_string(write, valueToString(value.asUInt()));
break;
case realValue:
write_string(write, valueToString(value.asDouble()));
break;
case stringValue:
write_string(write, valueToQuotedString(value.asCString()));
break;
case booleanValue:
write_string(write, valueToString(value.asBool()));
break;
case arrayValue:
{
write("[", 1);
int const size = value.size();
for (int index = 0; index < size; ++index)
{
if (index > 0)
write(",", 1);
write_value(write, value[index]);
}
write("]", 1);
break;
}
case objectValue:
{
Value::Members const members = value.getMemberNames();
write("{", 1);
for (auto it = members.begin(); it != members.end(); ++it)
{
std::string const& name = *it;
if (it != members.begin())
write(",", 1);
write_string(write, valueToQuotedString(name.c_str()));
write(":", 1);
write_value(write, value[name]);
}
write("}", 1);
break;
}
}
}
} // namespace detail
/** Stream compact JSON to the specified function.
@param jv The Json::Value to write
@param write Invocable with signature void(void const*, std::size_t) that
is called when output should be written to the stream.
*/
template <class Write>
void
stream(Json::Value const& jv, Write const& write)
{
detail::write_value(write, jv);
write("\n", 1);
}
/** Decorator for streaming out compact json
Use
Json::Value jv;
out << Json::Compact{jv}
to write a single-line, compact version of `jv` to the stream, rather
than the styled format that comes from undecorated streaming.
*/
class Compact
{
Json::Value jv_;
public:
/** Wrap a Json::Value for compact streaming
@param jv The Json::Value to stream
@note For now, we do not support wrapping lvalues to avoid
potentially costly copies. If we find a need, we can consider
adding support for compact lvalue streaming in the future.
*/
Compact(Json::Value&& jv) : jv_{std::move(jv)}
{
}
friend std::ostream&
operator<<(std::ostream& o, Compact const& cJv)
{
detail::write_value(
[&o](void const* data, std::size_t n) {
o.write(static_cast<char const*>(data), n);
},
cJv.jv_);
return o;
}
};
} // namespace Json
#endif // JSON_WRITER_H_INCLUDED

View File

@@ -27,6 +27,7 @@
#include <ripple/server/WSSession.h>
#include <ripple/rpc/RPCHandler.h>
#include <ripple/app/main/CollectorManager.h>
#include <ripple/json/Output.h>
#include <map>
#include <mutex>
#include <vector>

View File

@@ -23,8 +23,7 @@
#include <ripple/server/WSSession.h>
#include <ripple/net/InfoSub.h>
#include <ripple/beast/net/IPAddressConversion.h>
#include <ripple/json/Output.h>
#include <ripple/json/to_string.h>
#include <ripple/json/json_writer.h>
#include <ripple/rpc/Role.h>
#include <memory>
#include <string>
@@ -75,7 +74,7 @@ public:
if(! sp)
return;
beast::multi_buffer sb;
stream(jv,
Json::stream(jv,
[&](void const* data, std::size_t n)
{
sb.commit(boost::asio::buffer_copy(

View File

@@ -20,6 +20,7 @@
#include <BeastConfig.h>
#include <ripple/json/json_value.h>
#include <ripple/json/json_reader.h>
#include <ripple/json/json_writer.h>
#include <ripple/beast/unit_test.h>
#include <ripple/beast/type_name.h>
@@ -222,6 +223,32 @@ struct json_value_test : beast::unit_test::suite
testGreaterThan ("big");
}
void test_compact ()
{
Json::Value j;
Json::Reader r;
char const* s ("{\"array\":[{\"12\":23},{},null,false,0.5]}");
auto countLines = [](std::string const & s)
{
return 1 + std::count_if(s.begin(), s.end(), [](char c){
return c == '\n';
});
};
BEAST_EXPECT(r.parse(s,j));
{
std::stringstream ss;
ss << j;
BEAST_EXPECT(countLines(ss.str()) > 1);
}
{
std::stringstream ss;
ss << Json::Compact(std::move(j));
BEAST_EXPECT(countLines(ss.str()) == 1);
}
}
void run ()
{
test_bool ();
@@ -230,6 +257,7 @@ struct json_value_test : beast::unit_test::suite
test_copy ();
test_move ();
test_comparisons ();
test_compact ();
}
};