mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
@@ -23,6 +23,7 @@
|
|||||||
#include <xrpl/beast/utility/instrumentation.h>
|
#include <xrpl/beast/utility/instrumentation.h>
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <source_location>
|
#include <source_location>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -84,140 +85,140 @@ namespace detail {
|
|||||||
class SimpleJsonWriter
|
class SimpleJsonWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SimpleJsonWriter(std::string& stream) : stream_(stream)
|
explicit SimpleJsonWriter(std::string& buffer) : buffer_(buffer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
startObject() const
|
startObject() const
|
||||||
{
|
{
|
||||||
stream_.push_back('{');
|
buffer_.push_back('{');
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
endObject() const
|
endObject() const
|
||||||
{
|
{
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
stream_.pop_back();
|
buffer_.pop_back();
|
||||||
stream_.append("},"sv);
|
buffer_.append("},"sv);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeKey(std::string_view key) const
|
writeKey(std::string_view key) const
|
||||||
{
|
{
|
||||||
writeString(key);
|
writeString(key);
|
||||||
stream_.back() = ':';
|
buffer_.back() = ':';
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
startArray() const
|
startArray() const
|
||||||
{
|
{
|
||||||
stream_.push_back('[');
|
buffer_.push_back('[');
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
endArray() const
|
endArray() const
|
||||||
{
|
{
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
stream_.pop_back();
|
buffer_.pop_back();
|
||||||
stream_.append("],"sv);
|
buffer_.append("],"sv);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeString(std::string_view str) const
|
writeString(std::string_view str) const
|
||||||
{
|
{
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
stream_.push_back('"');
|
buffer_.push_back('"');
|
||||||
escape(str, stream_);
|
escape(str, buffer_);
|
||||||
stream_.append("\","sv);
|
buffer_.append("\","sv);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeInt(std::int8_t val) const
|
writeInt(std::int8_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeInt(std::int16_t val) const
|
writeInt(std::int16_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeInt(std::int32_t val) const
|
writeInt(std::int32_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeInt(std::int64_t val) const
|
writeInt(std::int64_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeUInt(std::size_t val) const
|
writeUInt(std::size_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeUInt(std::uint8_t val) const
|
writeUInt(std::uint8_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeUInt(std::uint16_t val) const
|
writeUInt(std::uint16_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeUInt(std::uint32_t val) const
|
writeUInt(std::uint32_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeUInt(std::uint64_t val) const
|
writeUInt(std::uint64_t val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeDouble(double val) const
|
writeDouble(double val) const
|
||||||
{
|
{
|
||||||
return pushNumber(val, stream_);
|
return pushNumber(val, buffer_);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeBool(bool val) const
|
writeBool(bool val) const
|
||||||
{
|
{
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
auto str = val ? "true,"sv : "false,"sv;
|
auto str = val ? "true,"sv : "false,"sv;
|
||||||
stream_.append(str);
|
buffer_.append(str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeNull() const
|
writeNull() const
|
||||||
{
|
{
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
stream_.append("null,"sv);
|
buffer_.append("null,"sv);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeRaw(std::string_view str) const
|
writeRaw(std::string_view str) const
|
||||||
{
|
{
|
||||||
stream_.append(str);
|
buffer_.append(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string_view
|
[[nodiscard]] std::string_view
|
||||||
finish()
|
finish()
|
||||||
{
|
{
|
||||||
return std::string_view{stream_.c_str(), stream_.size() - 1};
|
return std::string_view{buffer_.c_str(), buffer_.size() - 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::string_view
|
static std::string_view
|
||||||
pushNumber(T val, std::string& stream)
|
pushNumber(T val, std::string& str)
|
||||||
{
|
{
|
||||||
thread_local char buffer[128];
|
thread_local char buffer[128];
|
||||||
auto result = std::to_chars(std::begin(buffer), std::end(buffer), val);
|
auto result = std::to_chars(std::begin(buffer), std::end(buffer), val);
|
||||||
auto ptr = result.ptr;
|
auto ptr = result.ptr;
|
||||||
*ptr = ',';
|
*ptr = ',';
|
||||||
auto len = ptr - std::begin(buffer);
|
auto len = ptr - std::begin(buffer);
|
||||||
stream.append(buffer, len + 1);
|
str.append(buffer, len + 1);
|
||||||
return {buffer, static_cast<size_t>(len)};
|
return {buffer, static_cast<size_t>(len)};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
escape(std::string_view str, std::string& os)
|
escape(std::string_view str, std::string& buffer)
|
||||||
{
|
{
|
||||||
static constexpr char HEX[] = "0123456789ABCDEF";
|
static constexpr char HEX[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
@@ -240,36 +241,36 @@ private:
|
|||||||
|
|
||||||
// Flush the preceding safe run in one go.
|
// Flush the preceding safe run in one go.
|
||||||
if (chunk != p)
|
if (chunk != p)
|
||||||
os.append(chunk, p - chunk);
|
buffer.append(chunk, p - chunk);
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case '"':
|
case '"':
|
||||||
os.append("\\\"", 2);
|
buffer.append("\\\"", 2);
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\\':
|
||||||
os.append("\\\\", 2);
|
buffer.append("\\\\", 2);
|
||||||
break;
|
break;
|
||||||
case '\b':
|
case '\b':
|
||||||
os.append("\\b", 2);
|
buffer.append("\\b", 2);
|
||||||
break;
|
break;
|
||||||
case '\f':
|
case '\f':
|
||||||
os.append("\\f", 2);
|
buffer.append("\\f", 2);
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
os.append("\\n", 2);
|
buffer.append("\\n", 2);
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
os.append("\\r", 2);
|
buffer.append("\\r", 2);
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
os.append("\\t", 2);
|
buffer.append("\\t", 2);
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
// Other C0 controls -> \u00XX (JSON compliant)
|
// Other C0 controls -> \u00XX (JSON compliant)
|
||||||
char buf[6]{
|
char buf[6]{
|
||||||
'\\', 'u', '0', '0', HEX[(c >> 4) & 0xF], HEX[c & 0xF]};
|
'\\', 'u', '0', '0', HEX[(c >> 4) & 0xF], HEX[c & 0xF]};
|
||||||
os.append(buf, 6);
|
buffer.append(buf, 6);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,10 +281,10 @@ private:
|
|||||||
|
|
||||||
// Flush trailing safe run
|
// Flush trailing safe run
|
||||||
if (chunk != p)
|
if (chunk != p)
|
||||||
os.append(chunk, p - chunk);
|
buffer.append(chunk, p - chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string& stream_;
|
std::string& buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@@ -369,7 +370,7 @@ private:
|
|||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::string m_attributesJson;
|
std::string m_attributesJson;
|
||||||
static std::string globalLogAttributesJson_;
|
static std::string globalLogAttributesJson_;
|
||||||
static std::mutex globalLogAttributesMutex_;
|
static std::shared_mutex globalLogAttributesMutex_;
|
||||||
static bool m_jsonLogsEnabled;
|
static bool m_jsonLogsEnabled;
|
||||||
|
|
||||||
static thread_local JsonLogContext currentJsonLogContext_;
|
static thread_local JsonLogContext currentJsonLogContext_;
|
||||||
@@ -624,14 +625,14 @@ public:
|
|||||||
Journal(Journal const& other, TAttributesFactory&& attributesFactory)
|
Journal(Journal const& other, TAttributesFactory&& attributesFactory)
|
||||||
: m_name(other.m_name), m_sink(other.m_sink)
|
: m_name(other.m_name), m_sink(other.m_sink)
|
||||||
{
|
{
|
||||||
std::string stream{other.m_attributesJson};
|
std::string buffer{other.m_attributesJson};
|
||||||
detail::SimpleJsonWriter writer{stream};
|
detail::SimpleJsonWriter writer{buffer};
|
||||||
if (other.m_attributesJson.empty())
|
if (other.m_attributesJson.empty())
|
||||||
{
|
{
|
||||||
writer.startObject();
|
writer.startObject();
|
||||||
}
|
}
|
||||||
attributesFactory(writer);
|
attributesFactory(writer);
|
||||||
m_attributesJson = std::move(stream);
|
m_attributesJson = std::move(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a journal that writes to the specified sink. */
|
/** Create a journal that writes to the specified sink. */
|
||||||
@@ -648,11 +649,11 @@ public:
|
|||||||
TAttributesFactory&& attributesFactory)
|
TAttributesFactory&& attributesFactory)
|
||||||
: m_name(name), m_sink(&sink)
|
: m_name(name), m_sink(&sink)
|
||||||
{
|
{
|
||||||
std::string stream;
|
std::string buffer;
|
||||||
detail::SimpleJsonWriter writer{stream};
|
detail::SimpleJsonWriter writer{buffer};
|
||||||
writer.startObject();
|
writer.startObject();
|
||||||
attributesFactory(writer);
|
attributesFactory(writer);
|
||||||
m_attributesJson = std::move(stream);
|
m_attributesJson = std::move(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Journal&
|
Journal&
|
||||||
@@ -758,7 +759,7 @@ public:
|
|||||||
static void
|
static void
|
||||||
resetGlobalAttributes()
|
resetGlobalAttributes()
|
||||||
{
|
{
|
||||||
std::lock_guard lock(globalLogAttributesMutex_);
|
std::unique_lock lock(globalLogAttributesMutex_);
|
||||||
globalLogAttributesJson_.clear();
|
globalLogAttributesJson_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,17 +767,17 @@ public:
|
|||||||
static void
|
static void
|
||||||
addGlobalAttributes(TAttributesFactory&& factory)
|
addGlobalAttributes(TAttributesFactory&& factory)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(globalLogAttributesMutex_);
|
std::unique_lock lock(globalLogAttributesMutex_);
|
||||||
|
|
||||||
auto isEmpty = globalLogAttributesJson_.empty();
|
auto isEmpty = globalLogAttributesJson_.empty();
|
||||||
std::string stream{std::move(globalLogAttributesJson_)};
|
std::string buffer{std::move(globalLogAttributesJson_)};
|
||||||
detail::SimpleJsonWriter writer{stream};
|
detail::SimpleJsonWriter writer{buffer};
|
||||||
if (isEmpty)
|
if (isEmpty)
|
||||||
{
|
{
|
||||||
writer.startObject();
|
writer.startObject();
|
||||||
}
|
}
|
||||||
factory(writer);
|
factory(writer);
|
||||||
globalLogAttributesJson_ = std::move(stream);
|
globalLogAttributesJson_ = std::move(buffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,13 +22,14 @@
|
|||||||
#include <ios>
|
#include <ios>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
std::string Journal::globalLogAttributesJson_;
|
std::string Journal::globalLogAttributesJson_;
|
||||||
std::mutex Journal::globalLogAttributesMutex_;
|
std::shared_mutex Journal::globalLogAttributesMutex_;
|
||||||
bool Journal::m_jsonLogsEnabled = false;
|
bool Journal::m_jsonLogsEnabled = false;
|
||||||
thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{};
|
thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{};
|
||||||
|
|
||||||
@@ -150,13 +151,16 @@ Journal::JsonLogContext::reset(
|
|||||||
writer().endObject();
|
writer().endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!globalLogAttributesJson_.empty())
|
|
||||||
{
|
{
|
||||||
writer().writeKey("GlobalParams");
|
std::shared_lock lock(globalLogAttributesMutex_);
|
||||||
writer().writeRaw(std::string_view{
|
if (!globalLogAttributesJson_.empty())
|
||||||
std::begin(globalLogAttributesJson_),
|
{
|
||||||
std::end(globalLogAttributesJson_)});
|
writer().writeKey("GlobalParams");
|
||||||
writer().endObject();
|
writer().writeRaw(std::string_view{
|
||||||
|
std::begin(globalLogAttributesJson_),
|
||||||
|
std::end(globalLogAttributesJson_)});
|
||||||
|
writer().endObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer().writeKey("MessageParams");
|
writer().writeKey("MessageParams");
|
||||||
|
|||||||
@@ -231,32 +231,32 @@ TEST_CASE("Global attributes inheritable")
|
|||||||
TEST_CASE("Test JsonWriter")
|
TEST_CASE("Test JsonWriter")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::string stream;
|
std::string buffer;
|
||||||
beast::detail::SimpleJsonWriter writer{stream};
|
beast::detail::SimpleJsonWriter writer{buffer};
|
||||||
|
|
||||||
writer.writeString("\n");
|
writer.writeString("\n");
|
||||||
CHECK(writer.finish() == "\"\\n\"");
|
CHECK(writer.finish() == "\"\\n\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string stream;
|
std::string buffer;
|
||||||
beast::detail::SimpleJsonWriter writer{stream};
|
beast::detail::SimpleJsonWriter writer{buffer};
|
||||||
|
|
||||||
writer.writeString("\t");
|
writer.writeString("\t");
|
||||||
CHECK(writer.finish() == "\"\\t\"");
|
CHECK(writer.finish() == "\"\\t\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string stream;
|
std::string buffer;
|
||||||
beast::detail::SimpleJsonWriter writer{stream};
|
beast::detail::SimpleJsonWriter writer{buffer};
|
||||||
|
|
||||||
writer.writeString(std::string_view{"\0", 1});
|
writer.writeString(std::string_view{"\0", 1});
|
||||||
CHECK(writer.finish() == "\"\\u0000\"");
|
CHECK(writer.finish() == "\"\\u0000\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string stream;
|
std::string buffer;
|
||||||
beast::detail::SimpleJsonWriter writer{stream};
|
beast::detail::SimpleJsonWriter writer{buffer};
|
||||||
|
|
||||||
writer.writeString("\"\\");
|
writer.writeString("\"\\");
|
||||||
CHECK(writer.finish() == "\"\\\"\\\\\"");
|
CHECK(writer.finish() == "\"\\\"\\\\\"");
|
||||||
|
|||||||
Reference in New Issue
Block a user