performance optimisation

Signed-off-by: JCW <a1q123456@users.noreply.github.com>
This commit is contained in:
JCW
2025-08-29 22:19:35 +01:00
parent a128571ab5
commit e19d770b86
4 changed files with 199 additions and 203 deletions

View File

@@ -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())));
@@ -194,12 +200,11 @@ void
Logs::write(
beast::severities::Severity level,
std::string const& partition,
std::string const& text,
std::string text,
bool console)
{
std::string s;
format(s, text, level, partition);
std::lock_guard lock(mutex_);
format(s, std::move(text), level, partition);
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.";
@@ -328,15 +332,15 @@ Logs::fromString(std::string const& s)
void
Logs::format(
std::string& output,
std::string const& message,
std::string message,
beast::severities::Severity severity,
std::string const& partition)
{
output.reserve(message.size() + partition.size() + 100);
output = std::move(message);
if (!beast::Journal::isStructuredJournalEnabled())
{
output = to_string(std::chrono::system_clock::now());
output.reserve(message.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

@@ -154,135 +154,136 @@ Journal::JsonLogAttributes::setModuleName(std::string const& name)
allocator_);
}
Journal::JsonLogAttributes
void
Journal::JsonLogAttributes::combine(
AttributeFields const& a,
AttributeFields const& b)
AttributeFields const& from)
{
JsonLogAttributes result;
result.contextValues_.CopyFrom(a, result.allocator_);
for (auto& member : b.GetObject())
for (auto& member : from.GetObject())
{
auto val = rapidjson::Value{member.value, result.allocator_};
if (result.contextValues_.HasMember(member.name))
{
result.contextValues_[member.name] = std::move(val);
}
else
{
result.contextValues_.AddMember(
rapidjson::Value{member.name, result.allocator_},
std::move(val),
result.allocator_);
}
}
contextValues_.RemoveMember(member.name);
return result;
contextValues_.AddMember(
rapidjson::Value{member.name, allocator_},
rapidjson::Value{member.value, allocator_},
allocator_);
}
}
void
Journal::initMessageContext(std::source_location location)
Journal::JsonLogContext::reset(
std::source_location location,
severities::Severity severity,
std::optional<JsonLogAttributes> const& attributes) noexcept
{
currentJsonLogContext_.reset(location);
struct ThreadIdStringInitializer
{
std::string value;
ThreadIdStringInitializer()
{
std::stringstream threadIdStream;
threadIdStream << std::this_thread::get_id();
value = threadIdStream.str();
}
};
thread_local ThreadIdStringInitializer 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 const& message)
{
if (!m_jsonLogsEnabled)
{
return message;
}
rapidjson::Document doc{&currentJsonLogContext_.allocator};
rapidjson::Value logContext;
logContext.SetObject();
auto& attributes = currentJsonLogContext_.attributes();
logContext.AddMember(
rapidjson::StringRef("Function"),
rapidjson::StringRef(currentJsonLogContext_.location.function_name()),
currentJsonLogContext_.allocator);
logContext.AddMember(
rapidjson::StringRef("File"),
rapidjson::StringRef(currentJsonLogContext_.location.file_name()),
currentJsonLogContext_.allocator);
logContext.AddMember(
rapidjson::StringRef("Line"),
currentJsonLogContext_.location.line(),
currentJsonLogContext_.allocator);
std::stringstream threadIdStream;
threadIdStream << std::this_thread::get_id();
auto threadIdStr = threadIdStream.str();
logContext.AddMember(
rapidjson::StringRef("ThreadId"),
rapidjson::StringRef(threadIdStr.c_str()),
currentJsonLogContext_.allocator);
logContext.AddMember(
rapidjson::StringRef("Params"),
std::move(currentJsonLogContext_.messageParams),
currentJsonLogContext_.allocator);
currentJsonLogContext_.messageParams = rapidjson::Value{};
currentJsonLogContext_.messageParams.SetObject();
auto severityStr = to_string(severity);
logContext.AddMember(
rapidjson::StringRef("Level"),
rapidjson::StringRef(severityStr.c_str()),
currentJsonLogContext_.allocator);
logContext.AddMember(
attributes.RemoveMember("Message");
attributes.AddMember(
rapidjson::StringRef("Message"),
rapidjson::StringRef(message.c_str()),
currentJsonLogContext_.allocator);
logContext.AddMember(
rapidjson::StringRef("Time"),
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count(),
currentJsonLogContext_.allocator);
if (attributes.has_value())
{
for (auto const& [key, value] : attributes->contextValues().GetObject())
{
if (logContext.HasMember(key))
continue;
rapidjson::Value jsonValue;
jsonValue.CopyFrom(value, currentJsonLogContext_.allocator);
logContext.AddMember(
rapidjson::Value{key, currentJsonLogContext_.allocator},
std::move(jsonValue),
currentJsonLogContext_.allocator);
}
}
if (globalLogAttributes_)
{
for (auto const& [key, value] :
globalLogAttributes_->contextValues().GetObject())
{
if (logContext.HasMember(key))
continue;
rapidjson::Value jsonValue;
jsonValue.CopyFrom(value, currentJsonLogContext_.allocator);
logContext.AddMember(
rapidjson::Value{key, currentJsonLogContext_.allocator},
std::move(jsonValue),
currentJsonLogContext_.allocator);
}
}
rapidjson::Value{rapidjson::StringRef(message.c_str()), currentJsonLogContext_.allocator()},
currentJsonLogContext_.allocator()
);
rapidjson::StringBuffer buffer;
rapidjson::Writer writer(buffer);
logContext.Accept(writer);
attributes.Accept(writer);
return {buffer.GetString()};
}
@@ -345,21 +346,17 @@ 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;
}
@@ -370,9 +367,9 @@ Journal::ScopedStream::~ScopedStream()
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(s));
}
}
@@ -387,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