diff --git a/include/xrpl/beast/utility/Journal.h b/include/xrpl/beast/utility/Journal.h index 9a0b5436bb..2a3e5e3ff6 100644 --- a/include/xrpl/beast/utility/Journal.h +++ b/include/xrpl/beast/utility/Journal.h @@ -93,6 +93,9 @@ public: { } + std::string& + buffer() { return buffer_; } + void startObject() const { @@ -363,18 +366,18 @@ public: std::source_location location, severities::Severity severity, std::string_view moduleName, - std::string_view journalAttributesJson) noexcept; + std::string_view journalAttributes) noexcept; }; private: // Severity level / threshold of a Journal message. using Severity = severities::Severity; - std::string m_name; - std::string m_attributesJson; - static std::string globalLogAttributesJson_; + std::string name_; + std::string attributes_; + static std::string globalLogAttributes_; static std::shared_mutex globalLogAttributesMutex_; - static bool m_jsonLogsEnabled; + static bool jsonLogsEnabled_; static thread_local JsonLogContext currentJsonLogContext_; @@ -618,29 +621,29 @@ public: Journal() = delete; Journal(Journal const& other) - : m_name(other.m_name) - , m_attributesJson(other.m_attributesJson) + : name_(other.name_) + , attributes_(other.attributes_) , m_sink(other.m_sink) { } template Journal(Journal const& other, TAttributesFactory&& attributesFactory) - : m_name(other.m_name), m_sink(other.m_sink) + : name_(other.name_), m_sink(other.m_sink) { - std::string buffer{other.m_attributesJson}; + std::string buffer{other.attributes_}; detail::SimpleJsonWriter writer{buffer}; - if (other.m_attributesJson.empty()) + if (other.attributes_.empty() && jsonLogsEnabled_) { writer.startObject(); } attributesFactory(writer); - m_attributesJson = std::move(buffer); + attributes_ = std::move(buffer); } /** Create a journal that writes to the specified sink. */ explicit Journal(Sink& sink, std::string const& name = {}) - : m_name(name), m_sink(&sink) + : name_(name), m_sink(&sink) { } @@ -650,14 +653,14 @@ public: Sink& sink, std::string const& name, TAttributesFactory&& attributesFactory) - : m_name(name), m_sink(&sink) + : name_(name), m_sink(&sink) { std::string buffer; buffer.reserve(128); detail::SimpleJsonWriter writer{buffer}; writer.startObject(); attributesFactory(writer); - m_attributesJson = std::move(buffer); + attributes_ = std::move(buffer); } Journal& @@ -667,8 +670,8 @@ public: return *this; // LCOV_EXCL_LINE m_sink = other.m_sink; - m_name = other.m_name; - m_attributesJson = other.m_attributesJson; + name_ = other.name_; + attributes_ = other.attributes_; return *this; } @@ -676,8 +679,8 @@ public: operator=(Journal&& other) noexcept { m_sink = other.m_sink; - m_name = std::move(other.m_name); - m_attributesJson = std::move(other.m_attributesJson); + name_ = std::move(other.name_); + attributes_ = std::move(other.attributes_); return *this; } @@ -694,8 +697,7 @@ public: Severity level, std::source_location location = std::source_location::current()) const { - if (m_jsonLogsEnabled) - initMessageContext(location, level); + initMessageContext(location, level); return Stream(*m_sink, level); } @@ -714,48 +716,42 @@ public: Stream trace(std::source_location location = std::source_location::current()) const { - if (m_jsonLogsEnabled) - initMessageContext(location, severities::kTrace); + initMessageContext(location, severities::kTrace); return {*m_sink, severities::kTrace}; } Stream debug(std::source_location location = std::source_location::current()) const { - if (m_jsonLogsEnabled) - initMessageContext(location, severities::kDebug); + initMessageContext(location, severities::kDebug); return {*m_sink, severities::kDebug}; } Stream info(std::source_location location = std::source_location::current()) const { - if (m_jsonLogsEnabled) - initMessageContext(location, severities::kInfo); + initMessageContext(location, severities::kInfo); return {*m_sink, severities::kInfo}; } Stream warn(std::source_location location = std::source_location::current()) const { - if (m_jsonLogsEnabled) - initMessageContext(location, severities::kWarning); + initMessageContext(location, severities::kWarning); return {*m_sink, severities::kWarning}; } Stream error(std::source_location location = std::source_location::current()) const { - if (m_jsonLogsEnabled) - initMessageContext(location, severities::kError); + initMessageContext(location, severities::kError); return {*m_sink, severities::kError}; } Stream fatal(std::source_location location = std::source_location::current()) const { - if (m_jsonLogsEnabled) - initMessageContext(location, severities::kFatal); + initMessageContext(location, severities::kFatal); return {*m_sink, severities::kFatal}; } /** @} */ @@ -764,7 +760,7 @@ public: resetGlobalAttributes() { std::unique_lock lock(globalLogAttributesMutex_); - globalLogAttributesJson_.clear(); + globalLogAttributes_.clear(); } template @@ -772,10 +768,10 @@ public: addGlobalAttributes(TAttributesFactory&& factory) { std::unique_lock lock(globalLogAttributesMutex_); - globalLogAttributesJson_.reserve(128); - auto isEmpty = globalLogAttributesJson_.empty(); - detail::SimpleJsonWriter writer{globalLogAttributesJson_}; - if (isEmpty) + globalLogAttributes_.reserve(1024); + auto isEmpty = globalLogAttributes_.empty(); + detail::SimpleJsonWriter writer{globalLogAttributes_}; + if (isEmpty && jsonLogsEnabled_) { writer.startObject(); } @@ -905,6 +901,33 @@ concept StreamFormattable = requires(T val) { } -> std::convertible_to; }; +template +void +setTextValue( + beast::detail::SimpleJsonWriter& writer, + char const* name, + T&& value) +{ + using ValueType = std::decay_t; + writer.buffer() += name; + writer.buffer() += ": "; + if constexpr ( + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) + { + writer.buffer() += value; + } + else + { + std::ostringstream oss; + oss << value; + writer.buffer() += value;; + } + writer.buffer() += " "; +} + template void setJsonValue( @@ -1030,7 +1053,7 @@ template std::ostream& operator<<(std::ostream& os, LogParameter const& param) { - if (!beast::Journal::m_jsonLogsEnabled) + if (!beast::Journal::jsonLogsEnabled_) { os << param.value_; return os; @@ -1048,7 +1071,7 @@ template std::ostream& operator<<(std::ostream& os, LogField const& param) { - if (!beast::Journal::m_jsonLogsEnabled) + if (!beast::Journal::jsonLogsEnabled_) return os; beast::Journal::currentJsonLogContext_.startMessageParams(); detail::setJsonValue( @@ -1078,7 +1101,14 @@ template attributes(Pair&&... pairs) { return [&](beast::detail::SimpleJsonWriter& writer) { - (detail::setJsonValue(writer, pairs.first, pairs.second, nullptr), ...); + if (beast::Journal::isStructuredJournalEnabled()) + { + (detail::setJsonValue(writer, pairs.first, pairs.second, nullptr), ...); + } + else + { + (detail::setTextValue(writer, pairs.first, pairs.second), ...); + } }; } diff --git a/src/libxrpl/basics/Log.cpp b/src/libxrpl/basics/Log.cpp index 943951dec5..301fc2bd2d 100644 --- a/src/libxrpl/basics/Log.cpp +++ b/src/libxrpl/basics/Log.cpp @@ -202,7 +202,7 @@ Logs::write( } // Add to batch buffer for file output - { + if (false) { std::lock_guard lock(batchMutex_); // Console output still immediate for responsiveness diff --git a/src/libxrpl/beast/utility/beast_Journal.cpp b/src/libxrpl/beast/utility/beast_Journal.cpp index 89de4baaf9..b5163bad93 100644 --- a/src/libxrpl/beast/utility/beast_Journal.cpp +++ b/src/libxrpl/beast/utility/beast_Journal.cpp @@ -110,9 +110,9 @@ fastTimestampToString(std::int64_t milliseconds_since_epoch) } // anonymous namespace -std::string Journal::globalLogAttributesJson_; +std::string Journal::globalLogAttributes_; std::shared_mutex Journal::globalLogAttributesMutex_; -bool Journal::m_jsonLogsEnabled = false; +bool Journal::jsonLogsEnabled_ = false; thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{}; //------------------------------------------------------------------------------ @@ -208,7 +208,7 @@ Journal::JsonLogContext::reset( std::source_location location, severities::Severity severity, std::string_view moduleName, - std::string_view journalAttributesJson) noexcept + std::string_view journalAttributes) noexcept { struct ThreadIdStringInitializer { @@ -224,21 +224,26 @@ Journal::JsonLogContext::reset( buffer_.clear(); + if (!jsonLogsEnabled_) + { + return; + } + writer().startObject(); - if (!journalAttributesJson.empty()) + if (!journalAttributes.empty()) { writer().writeKey("Jnl"); - writer().writeRaw(journalAttributesJson); + writer().writeRaw(journalAttributes); writer().endObject(); } { std::shared_lock lock(globalLogAttributesMutex_); - if (!globalLogAttributesJson_.empty()) + if (!globalLogAttributes_.empty()) { writer().writeKey("Glb"); - writer().writeRaw(globalLogAttributesJson_); + writer().writeRaw(globalLogAttributes_); writer().endObject(); } } @@ -283,15 +288,17 @@ Journal::initMessageContext( std::source_location location, severities::Severity severity) const { - currentJsonLogContext_.reset(location, severity, m_name, m_attributesJson); + currentJsonLogContext_.reset(location, severity, name_, attributes_); } std::string_view Journal::formatLog(std::string const& message) { - if (!m_jsonLogsEnabled) + if (!jsonLogsEnabled_) { - return message; + currentJsonLogContext_.writer().buffer() += " "; + currentJsonLogContext_.writer().buffer() += message; + return currentJsonLogContext_.writer().buffer(); } auto& writer = currentJsonLogContext_.writer(); @@ -309,20 +316,20 @@ Journal::formatLog(std::string const& message) void Journal::enableStructuredJournal() { - m_jsonLogsEnabled = true; + jsonLogsEnabled_ = true; } void Journal::disableStructuredJournal() { - m_jsonLogsEnabled = false; + jsonLogsEnabled_ = false; resetGlobalAttributes(); } bool Journal::isStructuredJournalEnabled() { - return m_jsonLogsEnabled; + return jsonLogsEnabled_; } Journal::Sink::Sink(Severity thresh, bool console)