Compare commits

..

6 Commits

Author SHA1 Message Date
JCW
ddb103759f Fix issues
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-30 20:59:52 +01:00
JCW
1ff964a14a Fix issues
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-30 20:16:57 +01:00
JCW
8025cfad8d Fix issues
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-30 20:16:32 +01:00
JCW
8338a314e9 Optimisation
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-30 20:16:31 +01:00
JCW
bf7fcf3d39 Fix issues
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-30 20:16:29 +01:00
JCW
013cbac722 performance optimisation
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-30 20:15:00 +01:00
14 changed files with 303 additions and 232 deletions

View File

@@ -52,7 +52,6 @@ target_link_libraries(xrpl.libpb
add_library(xrpl.imports.main INTERFACE)
find_package(RapidJSON)
find_package(yyjson)
target_link_libraries(xrpl.imports.main
INTERFACE
@@ -78,7 +77,7 @@ add_module(xrpl beast)
target_link_libraries(xrpl.libxrpl.beast PUBLIC
xrpl.imports.main
xrpl.libpb
yyjson::yyjson
rapidjson
)
# Level 02

View File

@@ -30,8 +30,7 @@ class Xrpl(ConanFile):
'openssl/3.5.2',
'soci/4.0.3',
'zlib/1.3.1',
"rapidjson/1.1.0",
"yyjson/0.10.0"
"rapidjson/1.1.0"
]
test_requires = [

View File

@@ -68,11 +68,11 @@ private:
operator=(Sink const&) = delete;
void
write(beast::severities::Severity level, std::string const& text)
write(beast::severities::Severity level, std::string&& text)
override;
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override;
};
@@ -156,9 +156,10 @@ private:
private:
std::unique_ptr<std::ofstream> m_stream;
boost::filesystem::path m_path;
std::mutex mutable fileMutex_;
};
std::mutex mutable mutex_;
std::mutex mutable sinkSetMutex_;
std::map<
std::string,
std::unique_ptr<beast::Journal::Sink>,

View File

@@ -22,9 +22,9 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/json.hpp>
#include <rapidjson/document.h>
#include <memory>
#include <deque>
#include <optional>
#include <source_location>
#include <sstream>
@@ -129,26 +129,23 @@ public:
ripple::log::LogParameter<T> const& param);
class Sink;
class JsonLogAttributes
{
public:
using AttributeFields = boost::json::value;
using AttributeFields = rapidjson::Value;
JsonLogAttributes();
JsonLogAttributes(JsonLogAttributes const& other);
JsonLogAttributes(JsonLogAttributes&& other);
JsonLogAttributes&
operator=(JsonLogAttributes const& other);
JsonLogAttributes&
operator=(JsonLogAttributes&& other);
void
setModuleName(std::string const& name);
[[nodiscard]] static JsonLogAttributes
combine(AttributeFields const& a, AttributeFields const& b);
void
combine(AttributeFields const& from);
AttributeFields&
contextValues()
@@ -162,26 +159,50 @@ public:
return contextValues_;
}
rapidjson::MemoryPoolAllocator<>&
allocator()
{
return allocator_;
}
private:
AttributeFields contextValues_;
rapidjson::MemoryPoolAllocator<> allocator_;
friend class Journal;
};
struct JsonLogContext
class JsonLogContext
{
std::source_location location = {};
boost::json::value messageParams;
rapidjson::Value attributes_;
rapidjson::MemoryPoolAllocator<> allocator_;
public:
JsonLogContext() = default;
void
reset(std::source_location location_) noexcept
rapidjson::MemoryPoolAllocator<>&
allocator()
{
location = location_;
messageParams = {};
messageParams.emplace_object();
return allocator_;
}
rapidjson::Value&
messageParams()
{
return attributes_["Params"];
}
rapidjson::Value&
attributes()
{
return attributes_;
}
void
reset(
std::source_location location,
severities::Severity severity,
std::optional<JsonLogAttributes> const& attributes) noexcept;
};
private:
@@ -198,14 +219,13 @@ private:
// Invariant: m_sink always points to a valid Sink
Sink* m_sink = nullptr;
static void
initMessageContext(std::source_location location);
void
initMessageContext(
std::source_location location,
severities::Severity severity) const;
static std::string
formatLog(
std::string const& message,
severities::Severity severity,
std::optional<JsonLogAttributes> const& attributes = std::nullopt);
formatLog(std::string&& message);
public:
//--------------------------------------------------------------------------
@@ -259,7 +279,7 @@ public:
level is below the current threshold().
*/
virtual void
write(Severity level, std::string const& text) = 0;
write(Severity level, std::string&& text) = 0;
/** Bypass filter and write text to the sink at the specified severity.
* Always write the message, but maintain the same formatting as if
@@ -269,7 +289,7 @@ public:
* @param text Text to write to sink.
*/
virtual void
writeAlways(Severity level, std::string const& text) = 0;
writeAlways(Severity level, std::string&& text) = 0;
private:
Severity thresh_;
@@ -298,25 +318,16 @@ public:
{
public:
ScopedStream(ScopedStream const& other)
: ScopedStream(other.m_attributes, other.m_sink, other.m_level)
: ScopedStream(other.m_sink, other.m_level)
{
}
ScopedStream(
std::optional<JsonLogAttributes> attributes,
Sink& sink,
Severity level);
ScopedStream(Sink& sink, Severity level);
template <typename T>
ScopedStream(
std::optional<JsonLogAttributes> attributes,
Stream const& stream,
T const& t);
ScopedStream(Stream const& stream, T const& t);
ScopedStream(
std::optional<JsonLogAttributes> attributes,
Stream const& stream,
std::ostream& manip(std::ostream&));
ScopedStream(Stream const& stream, std::ostream& manip(std::ostream&));
ScopedStream&
operator=(ScopedStream const&) = delete;
@@ -337,7 +348,6 @@ public:
operator<<(T const& t) const;
private:
std::optional<JsonLogAttributes> m_attributes;
Sink& m_sink;
Severity const m_level;
std::ostringstream mutable m_ostream;
@@ -372,11 +382,7 @@ public:
Constructor is inlined so checking active() very inexpensive.
*/
Stream(
std::optional<JsonLogAttributes> attributes,
Sink& sink,
Severity level)
: m_attributes(std::move(attributes)), m_sink(sink), m_level(level)
Stream(Sink& sink, Severity level) : m_sink(sink), m_level(level)
{
XRPL_ASSERT(
m_level < severities::kDisabled,
@@ -384,8 +390,7 @@ public:
}
/** Construct or copy another Stream. */
Stream(Stream const& other)
: Stream(other.m_attributes, other.m_sink, other.m_level)
Stream(Stream const& other) : Stream(other.m_sink, other.m_level)
{
}
@@ -432,7 +437,6 @@ public:
/** @} */
private:
std::optional<JsonLogAttributes> m_attributes;
Sink& m_sink;
Severity m_level;
};
@@ -454,18 +458,15 @@ public:
Journal(
Journal const& other,
std::optional<JsonLogAttributes> attributes = std::nullopt)
: m_sink(other.m_sink)
: m_attributes(other.m_attributes)
, m_sink(other.m_sink)
{
if (attributes.has_value())
m_attributes = std::move(attributes.value());
if (other.m_attributes.has_value())
{
if (m_attributes.has_value())
m_attributes = JsonLogAttributes::combine(
other.m_attributes->contextValues_,
m_attributes->contextValues_);
if (m_attributes)
m_attributes->combine(attributes->contextValues_);
else
m_attributes = other.m_attributes;
m_attributes = std::move(attributes);
}
}
/** Create a journal that writes to the specified sink. */
@@ -510,9 +511,11 @@ public:
/** Returns a stream for this sink, with the specified severity level. */
Stream
stream(Severity level) const
stream(Severity level, std::source_location location = std::source_location::current()) const
{
return Stream(m_attributes, *m_sink, level);
if (m_jsonLogsEnabled)
initMessageContext(location, level);
return Stream(*m_sink, level);
}
/** Returns `true` if any message would be logged at this severity level.
@@ -531,48 +534,50 @@ public:
trace(std::source_location location = std::source_location::current()) const
{
if (m_jsonLogsEnabled)
initMessageContext(location);
return {m_attributes, *m_sink, 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);
return {m_attributes, *m_sink, 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);
return {m_attributes, *m_sink, severities::kInfo};
initMessageContext(location, severities::kInfo);
return {*m_sink, severities::kInfo};
}
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);
return {m_attributes, *m_sink, 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);
return {m_attributes, *m_sink, 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);
return {m_attributes, *m_sink, severities::kFatal};
initMessageContext(location, severities::kFatal);
return {*m_sink, severities::kFatal};
}
/** @} */
@@ -591,8 +596,7 @@ public:
{
globalLogAttributes_ = JsonLogAttributes{};
}
globalLogAttributes_ = JsonLogAttributes::combine(
globalLogAttributes_->contextValues(),
globalLogAttributes_->combine(
globalLogAttributes.contextValues());
}
};
@@ -609,11 +613,8 @@ static_assert(std::is_nothrow_destructible<Journal>::value == true, "");
//------------------------------------------------------------------------------
template <typename T>
Journal::ScopedStream::ScopedStream(
std::optional<JsonLogAttributes> attributes,
Stream const& stream,
T const& t)
: ScopedStream(std::move(attributes), stream.sink(), stream.level())
Journal::ScopedStream::ScopedStream(Stream const& stream, T const& t)
: ScopedStream(stream.sink(), stream.level())
{
m_ostream << t;
}
@@ -632,7 +633,7 @@ template <typename T>
Journal::ScopedStream
Journal::Stream::operator<<(T const& t) const
{
return {m_attributes, *this, t};
return {*this, t};
}
namespace detail {
@@ -707,21 +708,39 @@ using logwstream = basic_logstream<wchar_t>;
namespace ripple::log {
namespace detail {
template <typename T>
void
setJsonValue(
boost::json::value& object,
rapidjson::Value& object,
rapidjson::MemoryPoolAllocator<>& allocator,
char const* name,
T&& value,
std::ostream* outStream)
{
using ValueType = std::decay_t<T>;
auto& root = object.as_object();
if constexpr (std::constructible_from<boost::json::value, ValueType>)
rapidjson::Value jsonValue;
if constexpr (std::constructible_from<
rapidjson::Value,
ValueType,
rapidjson::MemoryPoolAllocator<>&>)
{
root[name] = std::forward<T>(value);
jsonValue = rapidjson::Value{value, allocator};
if (outStream)
{
(*outStream) << value;
}
}
else if constexpr (std::constructible_from<rapidjson::Value, ValueType>)
{
jsonValue = rapidjson::Value{value};
if (outStream)
{
(*outStream) << value;
}
}
else if constexpr (std::same_as<ValueType, std::string>)
{
jsonValue = rapidjson::Value{value.c_str(), allocator};
if (outStream)
{
(*outStream) << value;
@@ -732,13 +751,17 @@ setJsonValue(
std::ostringstream oss;
oss << value;
root[name] = oss.str();
jsonValue = rapidjson::Value{oss.str().c_str(), allocator};
if (outStream)
{
(*outStream) << oss.str();
}
}
object.RemoveMember(name);
object.AddMember(
rapidjson::StringRef(name), std::move(jsonValue), allocator);
}
} // namespace detail
@@ -749,7 +772,8 @@ operator<<(std::ostream& os, LogParameter<T> const& param)
if (!beast::Journal::m_jsonLogsEnabled)
return os;
detail::setJsonValue(
beast::Journal::currentJsonLogContext_.messageParams,
beast::Journal::currentJsonLogContext_.messageParams(),
beast::Journal::currentJsonLogContext_.allocator(),
param.name_,
param.value_,
&os);
@@ -763,7 +787,8 @@ operator<<(std::ostream& os, LogField<T> const& param)
if (!beast::Journal::m_jsonLogsEnabled)
return os;
detail::setJsonValue(
beast::Journal::currentJsonLogContext_.messageParams,
beast::Journal::currentJsonLogContext_.messageParams(),
beast::Journal::currentJsonLogContext_.allocator(),
param.name_,
param.value_,
nullptr);
@@ -791,7 +816,11 @@ attributes(Pair&&... pairs)
beast::Journal::JsonLogAttributes result;
(detail::setJsonValue(
result.contextValues(), pairs.first, pairs.second, nullptr),
result.contextValues(),
result.allocator(),
pairs.first,
pairs.second,
nullptr),
...);
return result;

View File

@@ -88,14 +88,14 @@ public:
}
void
write(beast::severities::Severity level, std::string const& text) override
write(beast::severities::Severity level, std::string&& text) override
{
using beast::Journal;
sink_.write(level, prefix_ + text);
}
void
writeAlways(severities::Severity level, std::string const& text) override
writeAlways(severities::Severity level, std::string&& text) override
{
using beast::Journal;
sink_.writeAlways(level, prefix_ + text);

View File

@@ -47,20 +47,20 @@ Logs::Sink::Sink(
}
void
Logs::Sink::write(beast::severities::Severity level, std::string const& text)
Logs::Sink::write(beast::severities::Severity level, std::string&& text)
{
if (level < threshold())
return;
logs_.write(level, partition_, text, console());
logs_.write(level, partition_, std::move(text), console());
}
void
Logs::Sink::writeAlways(
beast::severities::Severity level,
std::string const& text)
std::string&& text)
{
logs_.write(level, partition_, text, console());
logs_.write(level, partition_, std::move(text), console());
}
//------------------------------------------------------------------------------
@@ -88,9 +88,13 @@ Logs::File::open(boost::filesystem::path const& path)
if (stream->good())
{
std::lock_guard lock(fileMutex_);
m_path = path;
m_stream = std::move(stream);
size_t const bufsize = 256 * 1024;
static char buf[bufsize];
m_stream->rdbuf()->pubsetbuf(buf, bufsize);
wasOpened = true;
}
@@ -109,12 +113,14 @@ Logs::File::closeAndReopen()
void
Logs::File::close()
{
std::lock_guard lock(fileMutex_);
m_stream = nullptr;
}
void
Logs::File::write(char const* text)
{
std::lock_guard lock(fileMutex_);
if (m_stream != nullptr)
(*m_stream) << text;
}
@@ -122,10 +128,10 @@ Logs::File::write(char const* text)
void
Logs::File::writeln(char const* text)
{
std::lock_guard lock(fileMutex_);
if (m_stream != nullptr)
{
(*m_stream) << text;
(*m_stream) << std::endl;
(*m_stream) << text << '\n';
}
}
@@ -145,7 +151,7 @@ Logs::open(boost::filesystem::path const& pathToLogFile)
beast::Journal::Sink&
Logs::get(std::string const& name)
{
std::lock_guard lock(mutex_);
std::lock_guard lock(sinkSetMutex_);
auto const result = sinks_.emplace(name, makeSink(name, thresh_));
return *result.first->second;
}
@@ -173,7 +179,7 @@ Logs::threshold() const
void
Logs::threshold(beast::severities::Severity thresh)
{
std::lock_guard lock(mutex_);
std::lock_guard lock(sinkSetMutex_);
thresh_ = thresh;
for (auto& sink : sinks_)
sink.second->threshold(thresh);
@@ -183,7 +189,7 @@ std::vector<std::pair<std::string, std::string>>
Logs::partition_severities() const
{
std::vector<std::pair<std::string, std::string>> list;
std::lock_guard lock(mutex_);
std::lock_guard lock(sinkSetMutex_);
list.reserve(sinks_.size());
for (auto const& [name, sink] : sinks_)
list.emplace_back(name, toString(fromSeverity(sink->threshold())));
@@ -199,7 +205,6 @@ Logs::write(
{
std::string s;
format(s, text, level, partition);
std::lock_guard lock(mutex_);
file_.writeln(s);
if (!silent_)
std::cerr << s << '\n';
@@ -211,7 +216,6 @@ Logs::write(
std::string
Logs::rotate()
{
std::lock_guard lock(mutex_);
bool const wasOpened = file_.closeAndReopen();
if (wasOpened)
return "The log file was closed and reopened.";
@@ -332,11 +336,11 @@ Logs::format(
beast::severities::Severity severity,
std::string const& partition)
{
output.reserve(message.size() + partition.size() + 100);
output = message;
if (!beast::Journal::isStructuredJournalEnabled())
{
output = to_string(std::chrono::system_clock::now());
output.reserve(output.size() + partition.size() + 100);
output += to_string(std::chrono::system_clock::now());
output += " ";
if (!partition.empty())
@@ -369,8 +373,6 @@ Logs::format(
}
}
output += message;
// Limit the maximum length of the output
if (output.size() > maximumMessageCharacters)
{

View File

@@ -19,6 +19,10 @@
#include <xrpl/beast/utility/Journal.h>
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <ios>
#include <ostream>
#include <ranges>
@@ -73,12 +77,12 @@ public:
}
void
write(severities::Severity, std::string const&) override
write(severities::Severity, std::string&&) override
{
}
void
writeAlways(severities::Severity, std::string const&) override
writeAlways(severities::Severity, std::string&&) override
{
}
};
@@ -121,18 +125,13 @@ severities::to_string(Severity severity)
Journal::JsonLogAttributes::JsonLogAttributes()
{
contextValues_ = {};
contextValues_.emplace_object();
contextValues_.SetObject();
}
Journal::JsonLogAttributes::JsonLogAttributes(JsonLogAttributes const& other)
{
contextValues_ = other.contextValues_;
}
Journal::JsonLogAttributes::JsonLogAttributes(JsonLogAttributes&& other)
{
contextValues_ = std::move(other.contextValues_);
contextValues_.SetObject();
contextValues_.CopyFrom(other.contextValues_, allocator_);
}
Journal::JsonLogAttributes&
@@ -142,102 +141,151 @@ Journal::JsonLogAttributes::operator=(JsonLogAttributes const& other)
{
return *this;
}
contextValues_ = other.contextValues_;
return *this;
}
Journal::JsonLogAttributes&
Journal::JsonLogAttributes::operator=(JsonLogAttributes&& other)
{
if (&other == this)
{
return *this;
}
contextValues_ = std::move(other.contextValues_);
contextValues_.CopyFrom(other.contextValues_, allocator_);
return *this;
}
void
Journal::JsonLogAttributes::setModuleName(std::string const& name)
{
contextValues_.as_object()["Module"] = name;
}
Journal::JsonLogAttributes
Journal::JsonLogAttributes::combine(
AttributeFields const& a,
AttributeFields const& b)
{
JsonLogAttributes result;
result.contextValues_ = a;
for (auto& [key, value] : b.as_object())
{
result.contextValues_.as_object()[key] = value;
}
return result;
contextValues_.AddMember(
rapidjson::StringRef("Module"),
rapidjson::Value{name.c_str(), allocator_},
allocator_);
}
void
Journal::initMessageContext(std::source_location location)
Journal::JsonLogAttributes::combine(
AttributeFields const& from)
{
currentJsonLogContext_.reset(location);
for (auto& member : from.GetObject())
{
contextValues_.RemoveMember(member.name);
contextValues_.AddMember(
rapidjson::Value{member.name, allocator_},
rapidjson::Value{member.value, allocator_},
allocator_);
}
}
void
Journal::JsonLogContext::reset(
std::source_location location,
severities::Severity severity,
std::optional<JsonLogAttributes> const& attributes) noexcept
{
struct ThreadIdStringInitializer
{
std::string value;
ThreadIdStringInitializer()
{
std::stringstream threadIdStream;
threadIdStream << std::this_thread::get_id();
value = threadIdStream.str();
}
};
thread_local ThreadIdStringInitializer const threadId;
attributes_.SetObject();
if (globalLogAttributes_.has_value())
{
attributes_.CopyFrom(globalLogAttributes_->contextValues(), allocator_);
if (attributes.has_value())
{
for (auto const& [key, value] :
attributes->contextValues().GetObject())
{
attributes_.RemoveMember(key);
rapidjson::Value jsonValue;
jsonValue.CopyFrom(value, allocator_);
attributes_.AddMember(
rapidjson::Value{key, allocator_},
rapidjson::Value{value, allocator_},
allocator_);
}
}
}
else if (attributes.has_value())
{
attributes_.CopyFrom(attributes->contextValues(), allocator_);
}
attributes_.RemoveMember("Function");
attributes_.AddMember(
rapidjson::StringRef("Function"),
rapidjson::Value{location.function_name(), allocator_},
allocator_);
attributes_.RemoveMember("File");
attributes_.AddMember(
rapidjson::StringRef("File"),
rapidjson::Value{location.file_name(), allocator_},
allocator_);
attributes_.RemoveMember("Line");
attributes_.AddMember(
rapidjson::StringRef("Line"),
location.line(),
allocator_);
attributes_.RemoveMember("ThreadId");
attributes_.AddMember(
rapidjson::StringRef("ThreadId"),
rapidjson::Value{threadId.value.c_str(), allocator_},
allocator_);
attributes_.RemoveMember("Params");
attributes_.AddMember(
rapidjson::StringRef("Params"),
rapidjson::Value{rapidjson::kObjectType},
allocator_);
auto severityStr = to_string(severity);
attributes_.RemoveMember("Level");
attributes_.AddMember(
rapidjson::StringRef("Level"),
rapidjson::Value{severityStr.c_str(), allocator_},
allocator_);
attributes_.RemoveMember("Time");
attributes_.AddMember(
rapidjson::StringRef("Time"),
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count(),
allocator_);
}
void
Journal::initMessageContext(
std::source_location location,
severities::Severity severity) const
{
currentJsonLogContext_.reset(location, severity, m_attributes);
}
std::string
Journal::formatLog(
std::string const& message,
severities::Severity severity,
std::optional<JsonLogAttributes> const& attributes)
Journal::formatLog(std::string&& message)
{
if (!m_jsonLogsEnabled)
{
return message;
}
boost::json::value doc;
auto& attributes = currentJsonLogContext_.attributes();
if (globalLogAttributes_)
{
doc = globalLogAttributes_->contextValues_;
}
else
{
doc.emplace_object();
}
attributes.RemoveMember("Message");
attributes.AddMember(
rapidjson::StringRef("Message"),
rapidjson::Value{rapidjson::StringRef(message.c_str()), currentJsonLogContext_.allocator()},
currentJsonLogContext_.allocator()
);
if (attributes.has_value())
{
for (auto& [key, value] : attributes->contextValues_.as_object())
{
doc.as_object()[key] = value;
}
}
rapidjson::StringBuffer buffer;
rapidjson::Writer writer(buffer);
auto& logContext = doc.as_object();
attributes.Accept(writer);
logContext["Function"] = currentJsonLogContext_.location.function_name();
logContext["File"] = currentJsonLogContext_.location.file_name();
logContext["Line"] = currentJsonLogContext_.location.line();
std::stringstream threadIdStream;
threadIdStream << std::this_thread::get_id();
auto threadIdStr = threadIdStream.str();
logContext["ThreadId"] = threadIdStr;
logContext["Params"] = currentJsonLogContext_.messageParams;
auto severityStr = to_string(severity);
logContext["Level"] = severityStr;
logContext["Message"] = message;
logContext["Time"] =
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
return boost::json::serialize(doc);
return {buffer.GetString()};
}
void
@@ -298,34 +346,30 @@ Journal::Sink::threshold(Severity thresh)
//------------------------------------------------------------------------------
Journal::ScopedStream::ScopedStream(
std::optional<JsonLogAttributes> attributes,
Sink& sink,
Severity level)
: m_attributes(std::move(attributes)), m_sink(sink), m_level(level)
Journal::ScopedStream::ScopedStream(Sink& sink, Severity level)
: m_sink(sink), m_level(level)
{
// Modifiers applied from all ctors
m_ostream << std::boolalpha << std::showbase;
}
Journal::ScopedStream::ScopedStream(
std::optional<JsonLogAttributes> attributes,
Stream const& stream,
std::ostream& manip(std::ostream&))
: ScopedStream(std::move(attributes), stream.sink(), stream.level())
: ScopedStream(stream.sink(), stream.level())
{
m_ostream << manip;
}
Journal::ScopedStream::~ScopedStream()
{
std::string const& s(m_ostream.str());
std::string s = m_ostream.str();
if (!s.empty())
{
if (s == "\n")
m_sink.write(m_level, formatLog("", m_level, m_attributes));
m_sink.write(m_level, formatLog(""));
else
m_sink.write(m_level, formatLog(s, m_level, m_attributes));
m_sink.write(m_level, formatLog(std::move(s)));
}
}
@@ -340,7 +384,7 @@ Journal::ScopedStream::operator<<(std::ostream& manip(std::ostream&)) const
Journal::ScopedStream
Journal::Stream::operator<<(std::ostream& manip(std::ostream&)) const
{
return {m_attributes, *this, manip};
return {*this, manip};
}
} // namespace beast

View File

@@ -48,14 +48,14 @@ public:
}
void
write(severities::Severity level, std::string const&) override
write(severities::Severity level, std::string&&) override
{
if (level >= threshold())
++m_count;
}
void
writeAlways(severities::Severity level, std::string const&) override
writeAlways(severities::Severity level, std::string&&) override
{
++m_count;
}

View File

@@ -49,7 +49,7 @@ public:
}
void
write(beast::severities::Severity level, std::string const& text) override
write(beast::severities::Severity level, std::string&& text) override
{
if (level < threshold())
return;
@@ -59,7 +59,7 @@ public:
}
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override
{
std::cout << clock_.now().time_since_epoch().count() << " " << text

View File

@@ -57,7 +57,7 @@ class CaptureLogs : public Logs
}
void
write(beast::severities::Severity level, std::string const& text)
write(beast::severities::Severity level, std::string&& text)
override
{
std::lock_guard lock(strmMutex_);
@@ -65,7 +65,7 @@ class CaptureLogs : public Logs
}
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override
{
std::lock_guard lock(strmMutex_);

View File

@@ -45,7 +45,7 @@ class CheckMessageLogs : public Logs
}
void
write(beast::severities::Severity level, std::string const& text)
write(beast::severities::Severity level, std::string&& text)
override
{
if (text.find(owner_.msg_) != std::string::npos)
@@ -53,10 +53,10 @@ class CheckMessageLogs : public Logs
}
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override
{
write(level, text);
write(level, std::move(text));
}
};

View File

@@ -89,7 +89,7 @@ public:
}
void
write(beast::severities::Severity level, std::string const& text)
write(beast::severities::Severity level, std::string&& text)
override
{
if (level < threshold())
@@ -99,7 +99,7 @@ public:
}
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override
{
suite_.log << text << std::endl;

View File

@@ -49,27 +49,27 @@ public:
}
void
write(beast::severities::Severity level, std::string const& text) override;
write(beast::severities::Severity level, std::string&& text) override;
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override;
};
inline void
SuiteJournalSink::write(
beast::severities::Severity level,
std::string const& text)
std::string&& text)
{
// Only write the string if the level at least equals the threshold.
if (level >= threshold())
writeAlways(level, text);
writeAlways(level, std::move(text));
}
inline void
SuiteJournalSink::writeAlways(
beast::severities::Severity level,
std::string const& text)
std::string&& text)
{
using namespace beast::severities;
@@ -137,15 +137,15 @@ public:
}
void
write(beast::severities::Severity level, std::string const& text) override
write(beast::severities::Severity level, std::string&& text) override
{
if (level < threshold())
return;
writeAlways(level, text);
writeAlways(level, std::move(text));
}
inline void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override
{
strm_ << text << std::endl;

View File

@@ -49,14 +49,14 @@ private:
operator=(Sink const&) = delete;
void
write(beast::severities::Severity level, std::string const& text)
write(beast::severities::Severity level, std::string&& text)
override
{
logs_.logStream_ << text;
}
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override
{
logs_.logStream_ << text;
@@ -195,7 +195,6 @@ TEST_CASE("Global attributes inheritable")
CHECK(jsonLog.IsObject());
CHECK(jsonLog.HasMember("Field1"));
CHECK(jsonLog.HasMember("Field2"));
CHECK(jsonLog["Field1"].IsString());
// Field1 should be overwritten to Value3
CHECK(jsonLog["Field1"].GetString() == std::string{"Value3"});
@@ -218,13 +217,13 @@ public:
}
void
write(beast::severities::Severity level, std::string const& text) override
write(beast::severities::Severity level, std::string&& text) override
{
strm_ << text;
}
void
writeAlways(beast::severities::Severity level, std::string const& text)
writeAlways(beast::severities::Severity level, std::string&& text)
override
{
strm_ << text;
@@ -413,8 +412,6 @@ TEST_CASE_FIXTURE(JsonLogStreamFixture, "TestJsonLogParams")
"Field2",
std::numeric_limits<std::uint64_t>::max());
auto test = stream().str();
rapidjson::Document logValue;
logValue.Parse(stream().str().c_str());