mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 19:45:53 +00:00
Improve performance
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
This commit is contained in:
@@ -68,8 +68,7 @@ private:
|
||||
operator=(Sink const&) = delete;
|
||||
|
||||
void
|
||||
write(beast::severities::Severity level, std::string&& text)
|
||||
override;
|
||||
write(beast::severities::Severity level, std::string&& text) override;
|
||||
|
||||
void
|
||||
writeAlways(beast::severities::Severity level, std::string&& text)
|
||||
@@ -187,11 +186,19 @@ public:
|
||||
beast::Journal::Sink&
|
||||
operator[](std::string const& name);
|
||||
|
||||
template <typename AttributesFactory>
|
||||
beast::Journal
|
||||
journal(
|
||||
std::string const& name,
|
||||
std::optional<beast::Journal::JsonLogAttributes> attributes =
|
||||
std::nullopt);
|
||||
journal(std::string const& name, AttributesFactory&& factory)
|
||||
{
|
||||
return beast::Journal{
|
||||
get(name), name, std::forward<AttributesFactory>(factory)};
|
||||
}
|
||||
|
||||
beast::Journal
|
||||
journal(std::string const& name)
|
||||
{
|
||||
return beast::Journal{get(name), name};
|
||||
}
|
||||
|
||||
beast::severities::Severity
|
||||
threshold() const;
|
||||
|
||||
@@ -22,15 +22,6 @@
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/asio/execution/allocator.hpp>
|
||||
#include <boost/coroutine/attributes.hpp>
|
||||
#include <boost/system/result.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
#include <deque>
|
||||
#include <optional>
|
||||
#include <source_location>
|
||||
#include <sstream>
|
||||
@@ -86,6 +77,99 @@ operator<<(std::ostream& os, LogParameter<T> const& param);
|
||||
|
||||
namespace beast {
|
||||
|
||||
class SimpleJsonWriter
|
||||
{
|
||||
public:
|
||||
explicit SimpleJsonWriter(std::ostringstream& stream) : stream_(stream)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
startObject() const
|
||||
{
|
||||
stream_ << "{";
|
||||
}
|
||||
void
|
||||
endObject() const
|
||||
{
|
||||
stream_.seekp(-1, std::ios_base::end);
|
||||
stream_ << "},";
|
||||
}
|
||||
void
|
||||
writeKey(std::string_view key) const
|
||||
{
|
||||
writeString(key);
|
||||
stream_.seekp(-1, std::ios_base::end);
|
||||
stream_ << ":";
|
||||
}
|
||||
void
|
||||
startArray() const
|
||||
{
|
||||
stream_ << "[";
|
||||
}
|
||||
void
|
||||
endArray() const
|
||||
{
|
||||
stream_.seekp(-1, std::ios_base::end);
|
||||
stream_ << "],";
|
||||
}
|
||||
void
|
||||
writeString(std::string_view str) const
|
||||
{
|
||||
stream_ << "\"";
|
||||
escape(str, stream_);
|
||||
stream_ << "\",";
|
||||
}
|
||||
void
|
||||
writeInt(std::int64_t val) const
|
||||
{
|
||||
stream_ << val << ",";
|
||||
}
|
||||
void
|
||||
writeUInt(std::uint64_t val) const
|
||||
{
|
||||
stream_ << val << ",";
|
||||
}
|
||||
void
|
||||
writeDouble(double val) const
|
||||
{
|
||||
stream_ << val << ",";
|
||||
}
|
||||
void
|
||||
writeBool(bool val) const
|
||||
{
|
||||
stream_ << (val ? "true," : "false,");
|
||||
}
|
||||
void
|
||||
writeNull() const
|
||||
{
|
||||
stream_ << "null" << ",";
|
||||
}
|
||||
void
|
||||
writeRaw(std::string_view str) const
|
||||
{
|
||||
stream_ << str;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string
|
||||
str() const
|
||||
{
|
||||
auto result = stream_.str();
|
||||
result.pop_back();
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static void
|
||||
escape(std::string_view str, std::ostringstream& os)
|
||||
{
|
||||
// TODO: Support it
|
||||
os << str;
|
||||
}
|
||||
|
||||
std::ostringstream& stream_;
|
||||
};
|
||||
|
||||
/** A namespace for easy access to logging severity values. */
|
||||
namespace severities {
|
||||
/** Severity level / threshold of a Journal message. */
|
||||
@@ -136,94 +220,36 @@ public:
|
||||
|
||||
class Sink;
|
||||
|
||||
class JsonLogAttributes
|
||||
{
|
||||
public:
|
||||
using AttributeFields = rapidjson::Value;
|
||||
|
||||
JsonLogAttributes();
|
||||
JsonLogAttributes(JsonLogAttributes const& other);
|
||||
|
||||
JsonLogAttributes&
|
||||
operator=(JsonLogAttributes const& other);
|
||||
|
||||
void
|
||||
setModuleName(std::string const& name);
|
||||
|
||||
void
|
||||
combine(AttributeFields const& from);
|
||||
|
||||
AttributeFields&
|
||||
contextValues()
|
||||
{
|
||||
return contextValues_;
|
||||
}
|
||||
|
||||
[[nodiscard]] AttributeFields const&
|
||||
contextValues() const
|
||||
{
|
||||
return contextValues_;
|
||||
}
|
||||
|
||||
rapidjson::MemoryPoolAllocator<>&
|
||||
allocator()
|
||||
{
|
||||
return allocator_;
|
||||
}
|
||||
|
||||
private:
|
||||
AttributeFields contextValues_;
|
||||
rapidjson::MemoryPoolAllocator<> allocator_;
|
||||
|
||||
friend class Journal;
|
||||
};
|
||||
|
||||
class JsonLogContext
|
||||
{
|
||||
rapidjson::StringBuffer buffer_;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> messageParamsWriter_;
|
||||
std::optional<std::string> journalAttributesJson_;
|
||||
std::ostringstream buffer_;
|
||||
SimpleJsonWriter messageParamsWriter_;
|
||||
|
||||
public:
|
||||
JsonLogContext()
|
||||
: messageParamsWriter_(buffer_)
|
||||
JsonLogContext() : messageParamsWriter_(buffer_)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
rapidjson::Writer<rapidjson::StringBuffer>&
|
||||
SimpleJsonWriter&
|
||||
writer()
|
||||
{
|
||||
return messageParamsWriter_;
|
||||
}
|
||||
|
||||
char const*
|
||||
messageParams()
|
||||
{
|
||||
return buffer_.GetString();
|
||||
}
|
||||
|
||||
std::optional<std::string>&
|
||||
journalAttributesJson()
|
||||
{
|
||||
return journalAttributesJson_;
|
||||
}
|
||||
|
||||
void
|
||||
reset(
|
||||
std::source_location location,
|
||||
severities::Severity severity,
|
||||
std::optional<std::string> const& journalAttributesJson) noexcept;
|
||||
std::string const& journalAttributesJson) noexcept;
|
||||
};
|
||||
|
||||
private:
|
||||
// Severity level / threshold of a Journal message.
|
||||
using Severity = severities::Severity;
|
||||
|
||||
std::optional<JsonLogAttributes> m_attributes;
|
||||
std::optional<std::string> m_attributesJson;
|
||||
static std::optional<JsonLogAttributes> globalLogAttributes_;
|
||||
static std::optional<std::string> globalLogAttributesJson_;
|
||||
std::string m_name;
|
||||
std::string m_attributesJson;
|
||||
static std::string globalLogAttributesJson_;
|
||||
static std::mutex globalLogAttributesMutex_;
|
||||
static bool m_jsonLogsEnabled;
|
||||
|
||||
@@ -240,9 +266,6 @@ private:
|
||||
static std::string
|
||||
formatLog(std::string&& message);
|
||||
|
||||
void
|
||||
rebuildAttributeJson();
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -471,42 +494,46 @@ public:
|
||||
/** Journal has no default constructor. */
|
||||
Journal() = delete;
|
||||
|
||||
template <typename TAttributesFactory>
|
||||
Journal(
|
||||
Journal const& other,
|
||||
TAttributesFactory&& attributesFactory = nullptr)
|
||||
: m_attributes(other.m_attributes)
|
||||
, m_sink(other.m_sink)
|
||||
Journal(Journal const& other)
|
||||
: m_name(other.m_name)
|
||||
, m_attributesJson(other.m_attributesJson)
|
||||
, m_sink(other.m_sink)
|
||||
{
|
||||
/*
|
||||
if constexpr (!std::is_same_v<std::decay_t<TAttributesFactory>, std::nullptr_t>)
|
||||
}
|
||||
|
||||
template <typename TAttributesFactory>
|
||||
Journal(Journal const& other, TAttributesFactory&& attributesFactory)
|
||||
: m_name(other.m_name), m_sink(other.m_sink)
|
||||
{
|
||||
std::ostringstream stream{other.m_attributesJson, std::ios_base::app};
|
||||
SimpleJsonWriter writer{stream};
|
||||
if (other.m_attributesJson.empty())
|
||||
{
|
||||
if (attributes.has_value())
|
||||
{
|
||||
if (m_attributes)
|
||||
m_attributes->combine(attributes->contextValues_);
|
||||
else
|
||||
m_attributes = std::move(attributes);
|
||||
}
|
||||
rebuildAttributeJson();
|
||||
writer.startObject();
|
||||
}
|
||||
*/
|
||||
attributesFactory(writer);
|
||||
m_attributesJson = stream.str();
|
||||
}
|
||||
|
||||
/** Create a journal that writes to the specified sink. */
|
||||
explicit Journal(Sink& sink, std::string const& name = {})
|
||||
: m_name(name), m_sink(&sink)
|
||||
{
|
||||
}
|
||||
|
||||
/** Create a journal that writes to the specified sink. */
|
||||
template <typename TAttributesFactory>
|
||||
explicit Journal(
|
||||
Sink& sink,
|
||||
std::string const& name = {},
|
||||
std::optional<JsonLogAttributes> attributes = std::nullopt)
|
||||
: m_sink(&sink)
|
||||
std::string const& name,
|
||||
TAttributesFactory&& attributesFactory)
|
||||
: m_name(name), m_sink(&sink)
|
||||
{
|
||||
if (attributes)
|
||||
{
|
||||
m_attributes = std::move(attributes);
|
||||
m_attributes->setModuleName(name);
|
||||
}
|
||||
rebuildAttributeJson();
|
||||
std::ostringstream stream;
|
||||
SimpleJsonWriter writer{stream};
|
||||
writer.startObject();
|
||||
attributesFactory(writer);
|
||||
m_attributesJson = stream.str();
|
||||
}
|
||||
|
||||
Journal&
|
||||
@@ -516,8 +543,8 @@ public:
|
||||
return *this;
|
||||
|
||||
m_sink = other.m_sink;
|
||||
m_attributes = other.m_attributes;
|
||||
rebuildAttributeJson();
|
||||
m_name = other.m_name;
|
||||
m_attributesJson = other.m_attributesJson;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -525,8 +552,8 @@ public:
|
||||
operator=(Journal&& other) noexcept
|
||||
{
|
||||
m_sink = other.m_sink;
|
||||
m_attributes = std::move(other.m_attributes);
|
||||
rebuildAttributeJson();
|
||||
m_name = std::move(other.m_name);
|
||||
m_attributesJson = std::move(other.m_attributesJson);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -539,7 +566,9 @@ public:
|
||||
|
||||
/** Returns a stream for this sink, with the specified severity level. */
|
||||
Stream
|
||||
stream(Severity level, std::source_location location = std::source_location::current()) const
|
||||
stream(
|
||||
Severity level,
|
||||
std::source_location location = std::source_location::current()) const
|
||||
{
|
||||
if (m_jsonLogsEnabled)
|
||||
initMessageContext(location, level);
|
||||
@@ -585,8 +614,6 @@ public:
|
||||
Stream
|
||||
warn(std::source_location location = std::source_location::current()) const
|
||||
{
|
||||
char const* a = "a";
|
||||
rapidjson::Value v{a, 1};
|
||||
if (m_jsonLogsEnabled)
|
||||
initMessageContext(location, severities::kWarning);
|
||||
return {*m_sink, severities::kWarning};
|
||||
@@ -613,12 +640,26 @@ public:
|
||||
resetGlobalAttributes()
|
||||
{
|
||||
std::lock_guard lock(globalLogAttributesMutex_);
|
||||
globalLogAttributes_ = std::nullopt;
|
||||
globalLogAttributesJson_ = std::nullopt;
|
||||
globalLogAttributesJson_.clear();
|
||||
}
|
||||
|
||||
template <typename TAttributesFactory>
|
||||
static void
|
||||
addGlobalAttributes(JsonLogAttributes globalLogAttributes);
|
||||
addGlobalAttributes(TAttributesFactory&& factory)
|
||||
{
|
||||
std::lock_guard lock(globalLogAttributesMutex_);
|
||||
|
||||
auto isEmpty = globalLogAttributesJson_.empty();
|
||||
std::ostringstream stream{
|
||||
std::move(globalLogAttributesJson_), std::ios_base::app};
|
||||
SimpleJsonWriter writer{stream};
|
||||
if (isEmpty)
|
||||
{
|
||||
writer.startObject();
|
||||
}
|
||||
factory(writer);
|
||||
globalLogAttributesJson_ = stream.str();
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef __INTELLISENSE__
|
||||
@@ -728,25 +769,25 @@ using logwstream = basic_logstream<wchar_t>;
|
||||
namespace ripple::log {
|
||||
|
||||
namespace detail {
|
||||
template <typename T, typename OutputStream>
|
||||
template <typename T>
|
||||
void
|
||||
setJsonValue(
|
||||
rapidjson::Writer<OutputStream>& writer,
|
||||
beast::SimpleJsonWriter& writer,
|
||||
char const* name,
|
||||
T&& value,
|
||||
std::ostream* outStream)
|
||||
{
|
||||
using ValueType = std::decay_t<T>;
|
||||
writer.Key(name);
|
||||
writer.writeKey(name);
|
||||
if constexpr (std::is_integral_v<ValueType>)
|
||||
{
|
||||
if constexpr (std::is_signed_v<ValueType>)
|
||||
{
|
||||
writer.Int64(value);
|
||||
writer.writeInt(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Uint64(value);
|
||||
writer.writeUInt(value);
|
||||
}
|
||||
if (outStream)
|
||||
{
|
||||
@@ -755,7 +796,7 @@ setJsonValue(
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<ValueType>)
|
||||
{
|
||||
writer.Double(value);
|
||||
writer.writeDouble(value);
|
||||
|
||||
if (outStream)
|
||||
{
|
||||
@@ -764,15 +805,17 @@ setJsonValue(
|
||||
}
|
||||
else if constexpr (std::is_same_v<ValueType, bool>)
|
||||
{
|
||||
writer.Bool(value);
|
||||
writer.writeBool(value);
|
||||
if (outStream)
|
||||
{
|
||||
(*outStream) << value;
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_same_v<ValueType, char const*> || std::is_same_v<ValueType, char*>)
|
||||
else if constexpr (
|
||||
std::is_same_v<ValueType, char const*> ||
|
||||
std::is_same_v<ValueType, char*>)
|
||||
{
|
||||
writer.String(value);
|
||||
writer.writeString(value);
|
||||
if (outStream)
|
||||
{
|
||||
(*outStream) << value;
|
||||
@@ -780,7 +823,7 @@ setJsonValue(
|
||||
}
|
||||
else if constexpr (std::is_same_v<ValueType, std::string>)
|
||||
{
|
||||
writer.String(value.c_str(), value.length());
|
||||
writer.writeString(value);
|
||||
if (outStream)
|
||||
{
|
||||
(*outStream) << value;
|
||||
@@ -791,11 +834,13 @@ setJsonValue(
|
||||
std::ostringstream oss;
|
||||
oss << value;
|
||||
|
||||
writer.String(oss.str().c_str(), oss.str().length());
|
||||
auto str = oss.str();
|
||||
|
||||
writer.writeString(str);
|
||||
|
||||
if (outStream)
|
||||
{
|
||||
(*outStream) << oss.str();
|
||||
(*outStream) << str;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -847,13 +892,8 @@ template <typename... Pair>
|
||||
[[nodiscard]] auto
|
||||
attributes(Pair&&... pairs)
|
||||
{
|
||||
return [&](rapidjson::Writer<rapidjson::Writer<char>>& writer) {
|
||||
(detail::setJsonValue(
|
||||
writer,
|
||||
pairs.first,
|
||||
pairs.second,
|
||||
nullptr),
|
||||
...);
|
||||
return [&](beast::SimpleJsonWriter& writer) {
|
||||
(detail::setJsonValue(writer, pairs.first, pairs.second, nullptr), ...);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,7 @@ Logs::Sink::write(beast::severities::Severity level, std::string&& text)
|
||||
}
|
||||
|
||||
void
|
||||
Logs::Sink::writeAlways(
|
||||
beast::severities::Severity level,
|
||||
std::string&& text)
|
||||
Logs::Sink::writeAlways(beast::severities::Severity level, std::string&& text)
|
||||
{
|
||||
logs_.write(level, partition_, std::move(text), console());
|
||||
}
|
||||
@@ -162,14 +160,6 @@ Logs::operator[](std::string const& name)
|
||||
return get(name);
|
||||
}
|
||||
|
||||
beast::Journal
|
||||
Logs::journal(
|
||||
std::string const& name,
|
||||
std::optional<beast::Journal::JsonLogAttributes> attributes)
|
||||
{
|
||||
return beast::Journal{get(name), name, std::move(attributes)};
|
||||
}
|
||||
|
||||
beast::severities::Severity
|
||||
Logs::threshold() const
|
||||
{
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
#include <ios>
|
||||
#include <ostream>
|
||||
#include <ranges>
|
||||
@@ -31,9 +27,7 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
std::optional<Journal::JsonLogAttributes> Journal::globalLogAttributes_;
|
||||
std::optional<std::string> Journal::globalLogAttributesJson_;
|
||||
|
||||
std::string Journal::globalLogAttributesJson_;
|
||||
std::mutex Journal::globalLogAttributesMutex_;
|
||||
bool Journal::m_jsonLogsEnabled = false;
|
||||
thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{};
|
||||
@@ -125,75 +119,11 @@ severities::to_string(Severity severity)
|
||||
return "";
|
||||
}
|
||||
|
||||
Journal::JsonLogAttributes::JsonLogAttributes()
|
||||
{
|
||||
contextValues_.SetObject();
|
||||
}
|
||||
|
||||
Journal::JsonLogAttributes::JsonLogAttributes(JsonLogAttributes const& other)
|
||||
{
|
||||
contextValues_.SetObject();
|
||||
contextValues_.CopyFrom(other.contextValues_, allocator_);
|
||||
}
|
||||
|
||||
Journal::JsonLogAttributes&
|
||||
Journal::JsonLogAttributes::operator=(JsonLogAttributes const& other)
|
||||
{
|
||||
if (&other == this)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
contextValues_.CopyFrom(other.contextValues_, allocator_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
Journal::JsonLogAttributes::setModuleName(std::string const& name)
|
||||
{
|
||||
contextValues_.AddMember(
|
||||
rapidjson::StringRef("Module"),
|
||||
rapidjson::Value{name.c_str(), allocator_},
|
||||
allocator_);
|
||||
}
|
||||
|
||||
void
|
||||
Journal::JsonLogAttributes::combine(
|
||||
AttributeFields const& from)
|
||||
{
|
||||
for (auto& member : from.GetObject())
|
||||
{
|
||||
contextValues_.RemoveMember(member.name);
|
||||
|
||||
contextValues_.AddMember(
|
||||
rapidjson::Value{member.name, allocator_},
|
||||
rapidjson::Value{member.value, allocator_},
|
||||
allocator_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Journal::addGlobalAttributes(JsonLogAttributes globalLogAttributes)
|
||||
{
|
||||
std::lock_guard lock(globalLogAttributesMutex_);
|
||||
if (!globalLogAttributes_)
|
||||
{
|
||||
globalLogAttributes_ = JsonLogAttributes{};
|
||||
}
|
||||
globalLogAttributes_->combine(globalLogAttributes.contextValues());
|
||||
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer writer{buffer};
|
||||
|
||||
globalLogAttributes_->contextValues().Accept(writer);
|
||||
|
||||
globalLogAttributesJson_ = {buffer.GetString()};
|
||||
}
|
||||
|
||||
void
|
||||
Journal::JsonLogContext::reset(
|
||||
std::source_location location,
|
||||
severities::Severity severity,
|
||||
std::optional<std::string> const& journalAttributesJson) noexcept
|
||||
std::string const& journalAttributesJson) noexcept
|
||||
{
|
||||
struct ThreadIdStringInitializer
|
||||
{
|
||||
@@ -207,32 +137,47 @@ Journal::JsonLogContext::reset(
|
||||
};
|
||||
thread_local ThreadIdStringInitializer const threadId;
|
||||
|
||||
journalAttributesJson_ = journalAttributesJson;
|
||||
buffer_.str("");
|
||||
|
||||
buffer_.Clear();
|
||||
writer().startObject();
|
||||
|
||||
writer().StartObject();
|
||||
if (!journalAttributesJson.empty())
|
||||
{
|
||||
writer().writeKey("JournalParams");
|
||||
writer().writeRaw(journalAttributesJson);
|
||||
writer().endObject();
|
||||
}
|
||||
|
||||
writer().Key("Function");
|
||||
writer().String(location.function_name());
|
||||
if (!globalLogAttributesJson_.empty())
|
||||
{
|
||||
writer().writeKey("GlobalParams");
|
||||
writer().writeRaw(globalLogAttributesJson_);
|
||||
writer().endObject();
|
||||
}
|
||||
|
||||
writer().Key("File");
|
||||
writer().String(location.file_name());
|
||||
writer().writeKey("MessageParams");
|
||||
writer().startObject();
|
||||
|
||||
writer().Key("Line");
|
||||
writer().Int64(location.line());
|
||||
writer().writeKey("Function");
|
||||
writer().writeString(location.function_name());
|
||||
|
||||
writer().Key("ThreadId");
|
||||
writer().String(threadId.value.c_str());
|
||||
writer().writeKey("File");
|
||||
writer().writeString(location.file_name());
|
||||
|
||||
writer().writeKey("Line");
|
||||
writer().writeInt(location.line());
|
||||
|
||||
writer().writeKey("ThreadId");
|
||||
writer().writeString(threadId.value);
|
||||
|
||||
auto severityStr = to_string(severity);
|
||||
writer().Key("Level");
|
||||
writer().String(severityStr.c_str());
|
||||
writer().writeKey("Level");
|
||||
writer().writeString(severityStr);
|
||||
|
||||
writer().Key("Time");
|
||||
writer().Uint64(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
writer().writeKey("Time");
|
||||
writer().writeUInt(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -251,58 +196,16 @@ Journal::formatLog(std::string&& message)
|
||||
return message;
|
||||
}
|
||||
|
||||
currentJsonLogContext_.writer().EndObject();
|
||||
auto messageParams = currentJsonLogContext_.messageParams();
|
||||
auto& writer = currentJsonLogContext_.writer();
|
||||
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer writer(buffer);
|
||||
writer.endObject();
|
||||
|
||||
writer.StartObject();
|
||||
if (globalLogAttributesJson_.has_value())
|
||||
{
|
||||
writer.Key("GlobalParams");
|
||||
writer.RawValue(
|
||||
globalLogAttributesJson_->c_str(),
|
||||
globalLogAttributesJson_->length(),
|
||||
rapidjson::kObjectType);
|
||||
}
|
||||
writer.writeKey("Message");
|
||||
writer.writeString(message);
|
||||
|
||||
if (currentJsonLogContext_.journalAttributesJson().has_value())
|
||||
{
|
||||
writer.Key("JournalParams");
|
||||
writer.RawValue(
|
||||
currentJsonLogContext_.journalAttributesJson()->c_str(),
|
||||
currentJsonLogContext_.journalAttributesJson()->length(),
|
||||
rapidjson::kObjectType);
|
||||
}
|
||||
writer.endObject();
|
||||
|
||||
writer.Key("MessageParams");
|
||||
writer.RawValue(messageParams, std::strlen(messageParams), rapidjson::kObjectType);
|
||||
|
||||
writer.Key("Message");
|
||||
writer.String(message.c_str(), message.length());
|
||||
|
||||
writer.EndObject();
|
||||
|
||||
return {buffer.GetString()};
|
||||
}
|
||||
|
||||
void
|
||||
Journal::rebuildAttributeJson()
|
||||
{
|
||||
if (m_attributes.has_value())
|
||||
{
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer writer{buffer};
|
||||
|
||||
m_attributes->contextValues().Accept(writer);
|
||||
|
||||
m_attributesJson = {buffer.GetString()};
|
||||
}
|
||||
else
|
||||
{
|
||||
m_attributesJson = {};
|
||||
}
|
||||
return writer.str();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -59,8 +59,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
writeAlways(beast::severities::Severity level, std::string&& text)
|
||||
override
|
||||
writeAlways(beast::severities::Severity level, std::string&& text) override
|
||||
{
|
||||
std::cout << clock_.now().time_since_epoch().count() << " " << text
|
||||
<< std::endl;
|
||||
|
||||
@@ -57,8 +57,7 @@ class CaptureLogs : public Logs
|
||||
}
|
||||
|
||||
void
|
||||
write(beast::severities::Severity level, std::string&& text)
|
||||
override
|
||||
write(beast::severities::Severity level, std::string&& text) override
|
||||
{
|
||||
std::lock_guard lock(strmMutex_);
|
||||
strm_ << text;
|
||||
|
||||
@@ -45,8 +45,7 @@ class CheckMessageLogs : public Logs
|
||||
}
|
||||
|
||||
void
|
||||
write(beast::severities::Severity level, std::string&& text)
|
||||
override
|
||||
write(beast::severities::Severity level, std::string&& text) override
|
||||
{
|
||||
if (text.find(owner_.msg_) != std::string::npos)
|
||||
*owner_.pFound_ = true;
|
||||
|
||||
@@ -89,8 +89,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
write(beast::severities::Severity level, std::string&& text)
|
||||
override
|
||||
write(beast::severities::Severity level, std::string&& text) override
|
||||
{
|
||||
if (level < threshold())
|
||||
return;
|
||||
|
||||
@@ -52,14 +52,11 @@ public:
|
||||
write(beast::severities::Severity level, std::string&& text) override;
|
||||
|
||||
void
|
||||
writeAlways(beast::severities::Severity level, std::string&& text)
|
||||
override;
|
||||
writeAlways(beast::severities::Severity level, std::string&& text) override;
|
||||
};
|
||||
|
||||
inline void
|
||||
SuiteJournalSink::write(
|
||||
beast::severities::Severity level,
|
||||
std::string&& text)
|
||||
SuiteJournalSink::write(beast::severities::Severity level, std::string&& text)
|
||||
{
|
||||
// Only write the string if the level at least equals the threshold.
|
||||
if (level >= threshold())
|
||||
@@ -145,8 +142,7 @@ public:
|
||||
}
|
||||
|
||||
inline void
|
||||
writeAlways(beast::severities::Severity level, std::string&& text)
|
||||
override
|
||||
writeAlways(beast::severities::Severity level, std::string&& text) override
|
||||
{
|
||||
strm_ << text << std::endl;
|
||||
}
|
||||
|
||||
@@ -49,8 +49,7 @@ private:
|
||||
operator=(Sink const&) = delete;
|
||||
|
||||
void
|
||||
write(beast::severities::Severity level, std::string&& text)
|
||||
override
|
||||
write(beast::severities::Severity level, std::string&& text) override
|
||||
{
|
||||
logs_.logStream_ << text;
|
||||
}
|
||||
@@ -168,7 +167,8 @@ TEST_CASE("Global attributes")
|
||||
CHECK(jsonLog["GlobalParams"].IsObject());
|
||||
CHECK(jsonLog["GlobalParams"].HasMember("Field1"));
|
||||
CHECK(jsonLog["GlobalParams"]["Field1"].IsString());
|
||||
CHECK(jsonLog["GlobalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(
|
||||
jsonLog["GlobalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
beast::Journal::disableStructuredJournal();
|
||||
}
|
||||
|
||||
@@ -198,9 +198,14 @@ TEST_CASE("Global attributes inheritable")
|
||||
CHECK(jsonLog.IsObject());
|
||||
CHECK(jsonLog["GlobalParams"].HasMember("Field1"));
|
||||
CHECK(jsonLog["GlobalParams"]["Field1"].IsString());
|
||||
CHECK(jsonLog["GlobalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(jsonLog["JournalParams"]["Field1"].GetString() == std::string{"Value3"});
|
||||
CHECK(jsonLog["JournalParams"]["Field2"].GetString() == std::string{"Value2"});
|
||||
CHECK(
|
||||
jsonLog["GlobalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(
|
||||
jsonLog["JournalParams"]["Field1"].GetString() ==
|
||||
std::string{"Value3"});
|
||||
CHECK(
|
||||
jsonLog["JournalParams"]["Field2"].GetString() ==
|
||||
std::string{"Value2"});
|
||||
beast::Journal::disableStructuredJournal();
|
||||
}
|
||||
|
||||
@@ -224,8 +229,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
writeAlways(beast::severities::Severity level, std::string&& text)
|
||||
override
|
||||
writeAlways(beast::severities::Severity level, std::string&& text) override
|
||||
{
|
||||
strm_ << text;
|
||||
}
|
||||
@@ -235,9 +239,8 @@ class JsonLogStreamFixture
|
||||
{
|
||||
public:
|
||||
JsonLogStreamFixture()
|
||||
: sink_(beast::severities::kAll, logStream_), j_(sink_, "Test", log::attributes(
|
||||
log::attr("Field1", "Value1")
|
||||
))
|
||||
: sink_(beast::severities::kAll, logStream_)
|
||||
, j_(sink_, "Test", log::attributes(log::attr("Field1", "Value1")))
|
||||
{
|
||||
beast::Journal::enableStructuredJournal();
|
||||
}
|
||||
@@ -267,9 +270,11 @@ private:
|
||||
|
||||
TEST_CASE_FIXTURE(JsonLogStreamFixture, "TestJsonLogFields")
|
||||
{
|
||||
beast::Journal::addGlobalAttributes(log::attributes(log::attr("Field2", "Value2")));
|
||||
beast::Journal::addGlobalAttributes(
|
||||
log::attributes(log::attr("Field2", "Value2")));
|
||||
journal().debug() << std::boolalpha << true << std::noboolalpha << " Test "
|
||||
<< std::boolalpha << false << log::field("Field3", "Value3");
|
||||
<< std::boolalpha << false
|
||||
<< log::field("Field3", "Value3");
|
||||
|
||||
rapidjson::Document logValue;
|
||||
logValue.Parse(stream().str().c_str());
|
||||
@@ -484,7 +489,9 @@ TEST_CASE_FIXTURE(JsonLogStreamFixture, "TestJournalAttributes")
|
||||
logValue.GetParseError() == rapidjson::ParseErrorCode::kParseErrorNone);
|
||||
|
||||
CHECK(logValue["JournalParams"]["Field1"].IsString());
|
||||
CHECK(logValue["JournalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(
|
||||
logValue["JournalParams"]["Field1"].GetString() ==
|
||||
std::string{"Value1"});
|
||||
CHECK(logValue["JournalParams"]["Field2"].IsNumber());
|
||||
CHECK(logValue["JournalParams"]["Field2"].GetInt() == 2);
|
||||
}
|
||||
@@ -494,9 +501,7 @@ TEST_CASE_FIXTURE(JsonLogStreamFixture, "TestJournalAttributesInheritable")
|
||||
beast::Journal j{
|
||||
journal(),
|
||||
log::attributes(log::attr("Field1", "Value1"), log::attr("Field2", 2))};
|
||||
beast::Journal j2{
|
||||
j,
|
||||
log::attributes(log::attr("Field3", "Value3"), log::attr("Field2", 0))};
|
||||
beast::Journal j2{j, log::attributes(log::attr("Field3", "Value3"))};
|
||||
|
||||
j2.debug() << "Test";
|
||||
|
||||
@@ -507,12 +512,15 @@ TEST_CASE_FIXTURE(JsonLogStreamFixture, "TestJournalAttributesInheritable")
|
||||
logValue.GetParseError() == rapidjson::ParseErrorCode::kParseErrorNone);
|
||||
|
||||
CHECK(logValue["JournalParams"]["Field1"].IsString());
|
||||
CHECK(logValue["JournalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(
|
||||
logValue["JournalParams"]["Field1"].GetString() ==
|
||||
std::string{"Value1"});
|
||||
CHECK(logValue["JournalParams"]["Field3"].IsString());
|
||||
CHECK(logValue["JournalParams"]["Field3"].GetString() == std::string{"Value3"});
|
||||
// Field2 should be overwritten to 0
|
||||
CHECK(
|
||||
logValue["JournalParams"]["Field3"].GetString() ==
|
||||
std::string{"Value3"});
|
||||
CHECK(logValue["JournalParams"]["Field2"].IsNumber());
|
||||
CHECK(logValue["JournalParams"]["Field2"].GetInt() == 0);
|
||||
CHECK(logValue["JournalParams"]["Field2"].GetInt() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE_FIXTURE(
|
||||
@@ -522,9 +530,7 @@ TEST_CASE_FIXTURE(
|
||||
beast::Journal j{
|
||||
journal(),
|
||||
log::attributes(log::attr("Field1", "Value1"), log::attr("Field2", 2))};
|
||||
beast::Journal j2{
|
||||
j,
|
||||
log::attributes(log::attr("Field3", "Value3"), log::attr("Field2", 0))};
|
||||
beast::Journal j2{j, log::attributes(log::attr("Field3", "Value3"))};
|
||||
|
||||
j2.debug() << "Test";
|
||||
|
||||
@@ -535,12 +541,16 @@ TEST_CASE_FIXTURE(
|
||||
logValue.GetParseError() == rapidjson::ParseErrorCode::kParseErrorNone);
|
||||
|
||||
CHECK(logValue["JournalParams"]["Field1"].IsString());
|
||||
CHECK(logValue["JournalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(
|
||||
logValue["JournalParams"]["Field1"].GetString() ==
|
||||
std::string{"Value1"});
|
||||
CHECK(logValue["JournalParams"]["Field3"].IsString());
|
||||
CHECK(logValue["JournalParams"]["Field3"].GetString() == std::string{"Value3"});
|
||||
CHECK(
|
||||
logValue["JournalParams"]["Field3"].GetString() ==
|
||||
std::string{"Value3"});
|
||||
// Field2 should be overwritten to 0
|
||||
CHECK(logValue["JournalParams"]["Field2"].IsNumber());
|
||||
CHECK(logValue["JournalParams"]["Field2"].GetInt() == 0);
|
||||
CHECK(logValue["JournalParams"]["Field2"].GetInt() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE_FIXTURE(
|
||||
@@ -564,7 +574,9 @@ TEST_CASE_FIXTURE(
|
||||
logValue.GetParseError() == rapidjson::ParseErrorCode::kParseErrorNone);
|
||||
|
||||
CHECK(logValue["JournalParams"]["Field1"].IsString());
|
||||
CHECK(logValue["JournalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(
|
||||
logValue["JournalParams"]["Field1"].GetString() ==
|
||||
std::string{"Value1"});
|
||||
CHECK(logValue["JournalParams"]["Field2"].IsNumber());
|
||||
CHECK(logValue["JournalParams"]["Field2"].GetInt() == 2);
|
||||
}
|
||||
@@ -590,7 +602,9 @@ TEST_CASE_FIXTURE(
|
||||
logValue.GetParseError() == rapidjson::ParseErrorCode::kParseErrorNone);
|
||||
|
||||
CHECK(logValue["JournalParams"]["Field1"].IsString());
|
||||
CHECK(logValue["JournalParams"]["Field1"].GetString() == std::string{"Value1"});
|
||||
CHECK(
|
||||
logValue["JournalParams"]["Field1"].GetString() ==
|
||||
std::string{"Value1"});
|
||||
CHECK(logValue["JournalParams"]["Field2"].IsNumber());
|
||||
CHECK(logValue["JournalParams"]["Field2"].GetInt() == 2);
|
||||
}
|
||||
@@ -835,8 +835,11 @@ public:
|
||||
beast::Journal
|
||||
journal(
|
||||
std::string const& name,
|
||||
std::optional<beast::Journal::JsonLogAttributes> attributes =
|
||||
std::nullopt) override;
|
||||
std::function<void(beast::SimpleJsonWriter&)> const& attributes)
|
||||
override;
|
||||
|
||||
beast::Journal
|
||||
journal(std::string const& name) override;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -2173,11 +2176,17 @@ ApplicationImp::serverOkay(std::string& reason)
|
||||
beast::Journal
|
||||
ApplicationImp::journal(
|
||||
std::string const& name,
|
||||
std::optional<beast::Journal::JsonLogAttributes> attributes)
|
||||
std::function<void(beast::SimpleJsonWriter&)> const& attributes)
|
||||
{
|
||||
return logs_->journal(name, std::move(attributes));
|
||||
}
|
||||
|
||||
beast::Journal
|
||||
ApplicationImp::journal(std::string const& name)
|
||||
{
|
||||
return logs_->journal(name);
|
||||
}
|
||||
|
||||
void
|
||||
ApplicationImp::setMaxDisallowedLedger()
|
||||
{
|
||||
|
||||
@@ -260,8 +260,10 @@ public:
|
||||
virtual beast::Journal
|
||||
journal(
|
||||
std::string const& name,
|
||||
std::optional<beast::Journal::JsonLogAttributes> attributes =
|
||||
std::nullopt) = 0;
|
||||
std::function<void(beast::SimpleJsonWriter&)> const& attributes) = 0;
|
||||
|
||||
virtual beast::Journal
|
||||
journal(std::string const& name) = 0;
|
||||
|
||||
/* Returns the number of file descriptors the application needs */
|
||||
virtual int
|
||||
|
||||
Reference in New Issue
Block a user