Logging: made LogMessage contain a string view instead of const char*, added BufferSink, changed message parameter of formatted parameter to be string instead of const char*.

This commit is contained in:
Patrick Wuttke
2025-10-28 12:01:50 +01:00
parent 7d4c782b0f
commit 0e1964ba25
7 changed files with 450 additions and 40 deletions

View File

@@ -9,6 +9,7 @@
#include <mutex>
#include <source_location>
#include <string>
#include <string_view>
#include <vector>
#include "../internal/common.hpp"
#include "../util/annot.hpp"
@@ -78,12 +79,14 @@ struct BaseLogChannel
MIJIN_DEFINE_CHAR_VERSIONS(LogChannel)
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE>
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE, typename TTraits = std::char_traits<TChar>>
struct BaseLogMessage
{
using char_t = TChar;
using traits_t = TTraits;
using string_view_t = std::basic_string_view<char_t, traits_t>;
const char_t* text;
string_view_t text;
const BaseLogChannel<char_t>* channel;
const BaseLogLevel<char_t>* level;
std::source_location sourceLocation;
@@ -91,12 +94,13 @@ struct BaseLogMessage
MIJIN_DEFINE_CHAR_VERSIONS(LogMessage)
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE>
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE, typename TTraits = std::char_traits<TChar>>
class BaseLogSink
{
public:
using char_t = TChar;
using message_t = BaseLogMessage<char_t>;
using traits_t = TTraits;
using message_t = BaseLogMessage<char_t, traits_t>;
virtual ~BaseLogSink() noexcept = default;
@@ -105,12 +109,13 @@ public:
MIJIN_DEFINE_CHAR_VERSIONS(LogSink)
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE>
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE, typename TTraits = std::char_traits<TChar>>
class BaseLogFilter
{
public:
using char_t = TChar;
using message_t = BaseLogMessage<char_t>;
using traits_t = TTraits;
using message_t = BaseLogMessage<char_t, traits_t>;
virtual ~BaseLogFilter() noexcept = default;
@@ -128,12 +133,13 @@ public:
using traits_t = TTraits;
using allocator_t = TAllocator<char_t>;
using sink_t = BaseLogSink<char_t>;
using filter_t = BaseLogFilter<char_t>;
using sink_t = BaseLogSink<char_t, traits_t>;
using filter_t = BaseLogFilter<char_t, traits_t>;
using level_t = BaseLogLevel<char_t>;
using channel_t = BaseLogChannel<char_t>;
using message_t = BaseLogMessage<char_t>;
using message_t = BaseLogMessage<char_t, traits_t>;
using string_t = std::basic_string<char_t, traits_t, allocator_t>;
using string_view_t = std::basic_string_view<char_t, traits_t>;
private:
struct SinkEntry
{
@@ -146,13 +152,10 @@ public:
explicit BaseLogger(TAllocator<void> allocator = {}) MIJIN_NOEXCEPT_IF((std::is_nothrow_constructible_v<TAllocator<SinkEntry>, TAllocator<void>&&>))
: mSinks(TAllocator<SinkEntry>(std::move(allocator)))
{}
BaseLogger(const BaseLogger&) = default;
BaseLogger(BaseLogger&&) = default;
BaseLogger& operator=(const BaseLogger&) = default;
BaseLogger& operator=(BaseLogger&&) = default;
void addSink(sink_t& sink)
@@ -167,6 +170,19 @@ public:
mSinks.push_back({&sink, &filter});
}
bool removeSink(sink_t& sink)
{
std::unique_lock _(mMutex);
auto it = std::ranges::find_if(mSinks, [&](const SinkEntry& entry) {
return entry.sink == &sink;
});
if (it == mSinks.end()) {
return false;
}
mSinks.erase(it);
return true;
}
void postMessage(const message_t& message) const MIJIN_NOEXCEPT
{
std::unique_lock _(mMutex);
@@ -179,7 +195,7 @@ public:
}
}
void log(const level_t& level, const channel_t& channel, std::source_location sourceLocation, const char_t* msg) const MIJIN_NOEXCEPT
void logUnformatted(const level_t& level, const channel_t& channel, std::source_location sourceLocation, string_view_t msg) const MIJIN_NOEXCEPT
{
postMessage({
.text = msg,
@@ -189,6 +205,11 @@ public:
});
}
void log(const level_t& level, const channel_t& channel, std::source_location sourceLocation, std::basic_format_string<char_t> msg) const MIJIN_NOEXCEPT
{
logUnformatted(level, channel, sourceLocation, msg.get());
}
template<typename... TArgs>
void log(const level_t& level, const channel_t& channel, std::source_location sourceLocation,
std::basic_format_string<char_t, std::type_identity_t<TArgs>...> fmt, TArgs&& ... args) const
@@ -196,7 +217,7 @@ public:
{
string_t buffer(allocator_t(mSinks.get_allocator()));
std::format_to(std::back_inserter(buffer), fmt, std::forward<TArgs>(args)...);
log(level, channel, std::move(sourceLocation), buffer.c_str());
logUnformatted(level, channel, std::move(sourceLocation), buffer);
}
};
@@ -254,6 +275,9 @@ MIJIN_DEFINE_LOG_LEVEL(ERROR, MIJIN_LOG_LEVEL_VALUE_ERROR)
#define MIJIN_LOG_ALWAYS(level, channel, ...) MIJIN_FUNCNAME_GET_LOGGER().log( \
MIJIN_LOG_LEVEL_OBJECT(level), MIJIN_LOG_CHANNEL_OBJECT(channel), std::source_location::current(), __VA_ARGS__ \
)
#define MIJIN_LOG_ALWAYS_RAW(level, channel, ...) MIJIN_FUNCNAME_GET_LOGGER().logUnformatted( \
MIJIN_LOG_LEVEL_OBJECT(level), MIJIN_LOG_CHANNEL_OBJECT(channel), std::source_location::current(), __VA_ARGS__ \
)
#define MIJIN_LOG(level, channel, ...) \
if constexpr (MIJIN_LOG_LEVEL_OBJECT(level).value < MIJIN_FUNCNAME_MIN_LOG_LEVEL_COMPILE()) {} \
else MIJIN_LOG_ALWAYS(level, channel, __VA_ARGS__)
@@ -262,6 +286,14 @@ else MIJIN_LOG_ALWAYS(level, channel, __VA_ARGS__)
if constexpr (MIJIN_LOG_LEVEL_OBJECT(level).value < MIJIN_FUNCNAME_MIN_LOG_LEVEL_COMPILE()) {} \
else if (cond) MIJIN_LOG_ALWAYS(level, channel, __VA_ARGS__)
#define MIJIN_LOG_RAW(level, channel, ...) \
if constexpr (MIJIN_LOG_LEVEL_OBJECT(level).value < MIJIN_FUNCNAME_MIN_LOG_LEVEL_COMPILE()) {} \
else MIJIN_LOG_ALWAYS_RAW(level, channel, __VA_ARGS__)
#define MIJIN_LOG_IF_RAW(cond, level, channel, ...) \
if constexpr (MIJIN_LOG_LEVEL_OBJECT(level).value < MIJIN_FUNCNAME_MIN_LOG_LEVEL_COMPILE()) {} \
else if (cond) MIJIN_LOG_ALWAYS_RAW(level, channel, __VA_ARGS__)
#define MIJIN_SET_CLASS_LOGGER(loggerExpr) \
const auto& MIJIN_FUNCNAME_GET_LOGGER() const noexcept \
{ \