Performance test

Signed-off-by: JCW <a1q123456@users.noreply.github.com>
This commit is contained in:
JCW
2025-09-10 11:49:27 +01:00
parent 974e6067d8
commit 0c8a462e69
3 changed files with 91 additions and 54 deletions

View File

@@ -93,6 +93,9 @@ public:
{ {
} }
std::string&
buffer() { return buffer_; }
void void
startObject() const startObject() const
{ {
@@ -363,18 +366,18 @@ public:
std::source_location location, std::source_location location,
severities::Severity severity, severities::Severity severity,
std::string_view moduleName, std::string_view moduleName,
std::string_view journalAttributesJson) noexcept; std::string_view journalAttributes) noexcept;
}; };
private: private:
// Severity level / threshold of a Journal message. // Severity level / threshold of a Journal message.
using Severity = severities::Severity; using Severity = severities::Severity;
std::string m_name; std::string name_;
std::string m_attributesJson; std::string attributes_;
static std::string globalLogAttributesJson_; static std::string globalLogAttributes_;
static std::shared_mutex globalLogAttributesMutex_; static std::shared_mutex globalLogAttributesMutex_;
static bool m_jsonLogsEnabled; static bool jsonLogsEnabled_;
static thread_local JsonLogContext currentJsonLogContext_; static thread_local JsonLogContext currentJsonLogContext_;
@@ -618,29 +621,29 @@ public:
Journal() = delete; Journal() = delete;
Journal(Journal const& other) Journal(Journal const& other)
: m_name(other.m_name) : name_(other.name_)
, m_attributesJson(other.m_attributesJson) , attributes_(other.attributes_)
, m_sink(other.m_sink) , m_sink(other.m_sink)
{ {
} }
template <typename TAttributesFactory> template <typename TAttributesFactory>
Journal(Journal const& other, TAttributesFactory&& attributesFactory) 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}; detail::SimpleJsonWriter writer{buffer};
if (other.m_attributesJson.empty()) if (other.attributes_.empty() && jsonLogsEnabled_)
{ {
writer.startObject(); writer.startObject();
} }
attributesFactory(writer); attributesFactory(writer);
m_attributesJson = std::move(buffer); attributes_ = std::move(buffer);
} }
/** Create a journal that writes to the specified sink. */ /** Create a journal that writes to the specified sink. */
explicit Journal(Sink& sink, std::string const& name = {}) 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, Sink& sink,
std::string const& name, std::string const& name,
TAttributesFactory&& attributesFactory) TAttributesFactory&& attributesFactory)
: m_name(name), m_sink(&sink) : name_(name), m_sink(&sink)
{ {
std::string buffer; std::string buffer;
buffer.reserve(128); buffer.reserve(128);
detail::SimpleJsonWriter writer{buffer}; detail::SimpleJsonWriter writer{buffer};
writer.startObject(); writer.startObject();
attributesFactory(writer); attributesFactory(writer);
m_attributesJson = std::move(buffer); attributes_ = std::move(buffer);
} }
Journal& Journal&
@@ -667,8 +670,8 @@ public:
return *this; // LCOV_EXCL_LINE return *this; // LCOV_EXCL_LINE
m_sink = other.m_sink; m_sink = other.m_sink;
m_name = other.m_name; name_ = other.name_;
m_attributesJson = other.m_attributesJson; attributes_ = other.attributes_;
return *this; return *this;
} }
@@ -676,8 +679,8 @@ public:
operator=(Journal&& other) noexcept operator=(Journal&& other) noexcept
{ {
m_sink = other.m_sink; m_sink = other.m_sink;
m_name = std::move(other.m_name); name_ = std::move(other.name_);
m_attributesJson = std::move(other.m_attributesJson); attributes_ = std::move(other.attributes_);
return *this; return *this;
} }
@@ -694,8 +697,7 @@ public:
Severity level, Severity level,
std::source_location location = std::source_location::current()) const std::source_location location = std::source_location::current()) const
{ {
if (m_jsonLogsEnabled) initMessageContext(location, level);
initMessageContext(location, level);
return Stream(*m_sink, level); return Stream(*m_sink, level);
} }
@@ -714,48 +716,42 @@ public:
Stream Stream
trace(std::source_location location = std::source_location::current()) const 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}; return {*m_sink, severities::kTrace};
} }
Stream Stream
debug(std::source_location location = std::source_location::current()) const 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}; return {*m_sink, severities::kDebug};
} }
Stream Stream
info(std::source_location location = std::source_location::current()) const 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}; return {*m_sink, severities::kInfo};
} }
Stream Stream
warn(std::source_location location = std::source_location::current()) const 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}; return {*m_sink, severities::kWarning};
} }
Stream Stream
error(std::source_location location = std::source_location::current()) const 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}; return {*m_sink, severities::kError};
} }
Stream Stream
fatal(std::source_location location = std::source_location::current()) const 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}; return {*m_sink, severities::kFatal};
} }
/** @} */ /** @} */
@@ -764,7 +760,7 @@ public:
resetGlobalAttributes() resetGlobalAttributes()
{ {
std::unique_lock lock(globalLogAttributesMutex_); std::unique_lock lock(globalLogAttributesMutex_);
globalLogAttributesJson_.clear(); globalLogAttributes_.clear();
} }
template <typename TAttributesFactory> template <typename TAttributesFactory>
@@ -772,10 +768,10 @@ public:
addGlobalAttributes(TAttributesFactory&& factory) addGlobalAttributes(TAttributesFactory&& factory)
{ {
std::unique_lock lock(globalLogAttributesMutex_); std::unique_lock lock(globalLogAttributesMutex_);
globalLogAttributesJson_.reserve(128); globalLogAttributes_.reserve(1024);
auto isEmpty = globalLogAttributesJson_.empty(); auto isEmpty = globalLogAttributes_.empty();
detail::SimpleJsonWriter writer{globalLogAttributesJson_}; detail::SimpleJsonWriter writer{globalLogAttributes_};
if (isEmpty) if (isEmpty && jsonLogsEnabled_)
{ {
writer.startObject(); writer.startObject();
} }
@@ -905,6 +901,33 @@ concept StreamFormattable = requires(T val) {
} -> std::convertible_to<std::ostream&>; } -> std::convertible_to<std::ostream&>;
}; };
template <typename T>
void
setTextValue(
beast::detail::SimpleJsonWriter& writer,
char const* name,
T&& value)
{
using ValueType = std::decay_t<T>;
writer.buffer() += name;
writer.buffer() += ": ";
if constexpr (
std::is_same_v<ValueType, std::string> ||
std::is_same_v<ValueType, std::string_view> ||
std::is_same_v<ValueType, char const*> ||
std::is_same_v<ValueType, char*>)
{
writer.buffer() += value;
}
else
{
std::ostringstream oss;
oss << value;
writer.buffer() += value;;
}
writer.buffer() += " ";
}
template <typename T> template <typename T>
void void
setJsonValue( setJsonValue(
@@ -1030,7 +1053,7 @@ template <typename T>
std::ostream& std::ostream&
operator<<(std::ostream& os, LogParameter<T> const& param) operator<<(std::ostream& os, LogParameter<T> const& param)
{ {
if (!beast::Journal::m_jsonLogsEnabled) if (!beast::Journal::jsonLogsEnabled_)
{ {
os << param.value_; os << param.value_;
return os; return os;
@@ -1048,7 +1071,7 @@ template <typename T>
std::ostream& std::ostream&
operator<<(std::ostream& os, LogField<T> const& param) operator<<(std::ostream& os, LogField<T> const& param)
{ {
if (!beast::Journal::m_jsonLogsEnabled) if (!beast::Journal::jsonLogsEnabled_)
return os; return os;
beast::Journal::currentJsonLogContext_.startMessageParams(); beast::Journal::currentJsonLogContext_.startMessageParams();
detail::setJsonValue( detail::setJsonValue(
@@ -1078,7 +1101,14 @@ template <typename... Pair>
attributes(Pair&&... pairs) attributes(Pair&&... pairs)
{ {
return [&](beast::detail::SimpleJsonWriter& writer) { 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), ...);
}
}; };
} }

View File

@@ -202,7 +202,7 @@ Logs::write(
} }
// Add to batch buffer for file output // Add to batch buffer for file output
{ if (false) {
std::lock_guard lock(batchMutex_); std::lock_guard lock(batchMutex_);
// Console output still immediate for responsiveness // Console output still immediate for responsiveness

View File

@@ -110,9 +110,9 @@ fastTimestampToString(std::int64_t milliseconds_since_epoch)
} // anonymous namespace } // anonymous namespace
std::string Journal::globalLogAttributesJson_; std::string Journal::globalLogAttributes_;
std::shared_mutex Journal::globalLogAttributesMutex_; std::shared_mutex Journal::globalLogAttributesMutex_;
bool Journal::m_jsonLogsEnabled = false; bool Journal::jsonLogsEnabled_ = false;
thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{}; thread_local Journal::JsonLogContext Journal::currentJsonLogContext_{};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -208,7 +208,7 @@ Journal::JsonLogContext::reset(
std::source_location location, std::source_location location,
severities::Severity severity, severities::Severity severity,
std::string_view moduleName, std::string_view moduleName,
std::string_view journalAttributesJson) noexcept std::string_view journalAttributes) noexcept
{ {
struct ThreadIdStringInitializer struct ThreadIdStringInitializer
{ {
@@ -224,21 +224,26 @@ Journal::JsonLogContext::reset(
buffer_.clear(); buffer_.clear();
if (!jsonLogsEnabled_)
{
return;
}
writer().startObject(); writer().startObject();
if (!journalAttributesJson.empty()) if (!journalAttributes.empty())
{ {
writer().writeKey("Jnl"); writer().writeKey("Jnl");
writer().writeRaw(journalAttributesJson); writer().writeRaw(journalAttributes);
writer().endObject(); writer().endObject();
} }
{ {
std::shared_lock lock(globalLogAttributesMutex_); std::shared_lock lock(globalLogAttributesMutex_);
if (!globalLogAttributesJson_.empty()) if (!globalLogAttributes_.empty())
{ {
writer().writeKey("Glb"); writer().writeKey("Glb");
writer().writeRaw(globalLogAttributesJson_); writer().writeRaw(globalLogAttributes_);
writer().endObject(); writer().endObject();
} }
} }
@@ -283,15 +288,17 @@ Journal::initMessageContext(
std::source_location location, std::source_location location,
severities::Severity severity) const severities::Severity severity) const
{ {
currentJsonLogContext_.reset(location, severity, m_name, m_attributesJson); currentJsonLogContext_.reset(location, severity, name_, attributes_);
} }
std::string_view std::string_view
Journal::formatLog(std::string const& message) 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(); auto& writer = currentJsonLogContext_.writer();
@@ -309,20 +316,20 @@ Journal::formatLog(std::string const& message)
void void
Journal::enableStructuredJournal() Journal::enableStructuredJournal()
{ {
m_jsonLogsEnabled = true; jsonLogsEnabled_ = true;
} }
void void
Journal::disableStructuredJournal() Journal::disableStructuredJournal()
{ {
m_jsonLogsEnabled = false; jsonLogsEnabled_ = false;
resetGlobalAttributes(); resetGlobalAttributes();
} }
bool bool
Journal::isStructuredJournalEnabled() Journal::isStructuredJournalEnabled()
{ {
return m_jsonLogsEnabled; return jsonLogsEnabled_;
} }
Journal::Sink::Sink(Severity thresh, bool console) Journal::Sink::Sink(Severity thresh, bool console)