Fix issues

Signed-off-by: JCW <a1q123456@users.noreply.github.com>
This commit is contained in:
JCW
2025-09-02 20:04:14 +01:00
parent c2aae2d846
commit 1a2b7e9b94
3 changed files with 71 additions and 66 deletions

View File

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

View File

@@ -22,13 +22,14 @@
#include <ios>
#include <ostream>
#include <ranges>
#include <shared_mutex>
#include <string>
#include <thread>
namespace beast {
std::string Journal::globalLogAttributesJson_;
std::mutex Journal::globalLogAttributesMutex_;
std::shared_mutex Journal::globalLogAttributesMutex_;
bool Journal::m_jsonLogsEnabled = false;
thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{};
@@ -150,6 +151,8 @@ Journal::JsonLogContext::reset(
writer().endObject();
}
{
std::shared_lock lock(globalLogAttributesMutex_);
if (!globalLogAttributesJson_.empty())
{
writer().writeKey("GlobalParams");
@@ -158,6 +161,7 @@ Journal::JsonLogContext::reset(
std::end(globalLogAttributesJson_)});
writer().endObject();
}
}
writer().writeKey("MessageParams");
writer().startObject();

View File

@@ -231,32 +231,32 @@ TEST_CASE("Global attributes inheritable")
TEST_CASE("Test JsonWriter")
{
{
std::string stream;
beast::detail::SimpleJsonWriter writer{stream};
std::string buffer;
beast::detail::SimpleJsonWriter writer{buffer};
writer.writeString("\n");
CHECK(writer.finish() == "\"\\n\"");
}
{
std::string stream;
beast::detail::SimpleJsonWriter writer{stream};
std::string buffer;
beast::detail::SimpleJsonWriter writer{buffer};
writer.writeString("\t");
CHECK(writer.finish() == "\"\\t\"");
}
{
std::string stream;
beast::detail::SimpleJsonWriter writer{stream};
std::string buffer;
beast::detail::SimpleJsonWriter writer{buffer};
writer.writeString(std::string_view{"\0", 1});
CHECK(writer.finish() == "\"\\u0000\"");
}
{
std::string stream;
beast::detail::SimpleJsonWriter writer{stream};
std::string buffer;
beast::detail::SimpleJsonWriter writer{buffer};
writer.writeString("\"\\");
CHECK(writer.finish() == "\"\\\"\\\\\"");