16 template<sbo_poly_assignable_c<base_logger_stream> stream_t>
17 static constexpr
auto k_LoggerStreamFilter = [](
const logger::logger_sbo& stream)
19 return stream->is<stream_t>();
24 inline logger::logger() noexcept
30 inline logger::~logger() noexcept
35 template<sbo_poly_assignable_c<base_logger_stream> stream_t>
38 std::unique_lock _(m_StreamsMutex);
39 m_Streams.emplace_back(std::move(stream));
42 template<sbo_poly_assignable_c<base_logger_stream> stream_t>
45 auto it = std::ranges::find_if(m_Streams, details::k_LoggerStreamFilter<stream_t>);
46 return it != m_Streams.end() ?
static_cast<stream_t*
>(&it->get()) :
nullptr;
49 template<sbo_poly_assignable_c<base_logger_stream> stream_t>
52 return m_Streams | std::views::filter(details::k_LoggerStreamFilter<stream_t>)
53 | std::views::transform(
56 return static_cast<stream_t*
>(&stream.get());
62 return m_StreamsMutex;
65 template<sbo_poly_assignable_c<base_logger_stream> stream_t>
68 std::unique_lock _(m_StreamsMutex);
69 return std::erase_if(m_Streams, details::k_LoggerStreamFilter<stream_t>);
79 std::unique_lock _(m_RegisteredCategoriesMutex);
80 m_RegisteredCategories.try_emplace(std::move(sCategoryName), std::move(data));
85 category_data::format_user_message_func FormatUserMessage) noexcept
91 string_view svCategoryName,
92 category_data::format_user_message_func FormatUserMessage) noexcept
94 std::unique_lock _(m_RegisteredCategoriesMutex);
95 if (
auto it = m_RegisteredCategories.find(svCategoryName); it != m_RegisteredCategories.end())
97 it->second.FormatUserMessage = std::move(FormatUserMessage);
105 if (eResult == compile_pattern_result::ok)
106 m_sDefaultPattern = std::move(sPattern);
113 verbosity eVerbosity,
114 std::thread::id threadId,
115 std::chrono::system_clock::time_point messageTime,
117 string_view svFunction,
125 std::shared_lock _(m_RegisteredCategoriesMutex);
126 if (
auto itRegisteredCategory = m_RegisteredCategories.find(
category.
get_name());
127 itRegisteredCategory != m_RegisteredCategories.end())
130 if (data.FormatUserMessage)
132 message = data.FormatUserMessage(std::move(message), m_StringsPool);
137 if (eMessageNecessity != message_necessity_type::not_required)
142 finalLogMessage.sValue,
154 std::shared_lock _(m_StreamsMutex);
155 for (
auto& stream : m_Streams)
157 if (eMessageNecessity != message_necessity_type::one_of_streams_requires
158 || stream->log_unconditionally_required(
167 std::optional<logger_string_pool::item> optStreamLogMessage;
168 if (
const std::optional<string_view> optPattern = stream->get_pattern())
170 optStreamLogMessage = m_StringsPool.
acquire();
172 optStreamLogMessage->sValue,
192 optStreamLogMessage ? optStreamLogMessage->sValue : finalLogMessage.sValue);
194 if (optStreamLogMessage)
195 m_StringsPool.
release(std::move(*optStreamLogMessage));
200 m_StringsPool.
release(std::move(finalLogMessage));
203 m_StringsPool.
release(std::move(message));
208 std::shared_lock _(m_StreamsMutex);
209 for (
auto& stream : m_Streams)
218 std::unique_lock _(m_StreamsMutex);
223 std::unique_lock _(m_RegisteredCategoriesMutex);
224 m_RegisteredCategories.clear();
235 set_default_pattern(QXT(
"{verbosity:l}[{time:%d.%m.%Y_%H:%M:%S}]{category:l} {message}\n"));
240 verbosity eVerbosity,
241 std::thread::id threadId,
242 std::chrono::system_clock::time_point messageTime,
244 string_view svFunction,
245 int nLine)
const noexcept
249 std::shared_lock _(m_StreamsMutex);
250 const bool bSomeStreamRequires = std::ranges::any_of(
252 [&
category, eVerbosity, threadId, messageTime, svFile, svFunction, nLine](
const auto& stream)
254 return stream->log_unconditionally_required(
263 if (bSomeStreamRequires)
264 eMessageNecessity |= message_necessity_type::one_of_streams_requires;
268 std::shared_lock _(m_RegisteredCategoriesMutex);
269 if (
auto itRegisteredCategory = m_RegisteredCategories.find(
category.
get_name());
270 itRegisteredCategory != m_RegisteredCategories.end())
273 if (eVerbosity >= data.eRuntimeVerbosity)
274 eMessageNecessity |= message_necessity_type::category_verbosity;
278 if (eVerbosity >= verbosity::log)
279 eMessageNecessity |= message_necessity_type::default_verbosity;
281 return eMessageNecessity;
286 return &m_StringsPool;
A category is a class that identifies a particular piece of code. This code can be located in differe...
constexpr string_view get_name() const noexcept
Get category name.
Wrapper for enumerations to be used as a list of flags.
void set_category_formatter(const category &category, category_data::format_user_message_func FormatUserMessage) noexcept
Set category formatter.
size_t remove_streams() noexcept
Remove all the streams of the given type.
auto get_streams() noexcept
Get all the streams of the given type.
flags< message_necessity_type > get_message_necessity_type(const category &category, verbosity eVerbosity, std::thread::id threadId, std::chrono::system_clock::time_point messageTime, string_view svFile, string_view svFunction, int nLine) const noexcept
Check if this message will go somewhere.
void add_stream(stream_t stream) noexcept
Add an output stream to the logger.
void register_category(const category &category, category_data data) noexcept
Add custom rules for category.
std::shared_mutex & get_streams_mutex() noexcept
Get streams mutex.
stream_t * get_stream() noexcept
Get the first occurrence of a stream of the given type.
virtual void log_macro(const category &category, verbosity eVerbosity, std::thread::id threadId, std::chrono::system_clock::time_point messageTime, string_view svFile, string_view svFunction, int nLine, logger_string_pool::item message)
Main log function: log to all streams. For macro and internal usage.
virtual void reset() noexcept
Reset logger and clear all streams.
virtual void flush()
Flush all streams.
compile_pattern_result set_default_pattern(string sPattern) noexcept
Compile and set the default pattern for log messages.
Fixed-size atomic string pool.
item acquire()
Acquire a string from the pool.
void release(item item)
Return a string back to the pool.
Small Buffer Object for polymorphic classes.
void format_log_specifiers(string &sStorage, string_view svPattern, const category &category, verbosity eVerbosity, std::thread::id threadId, std::chrono::system_clock::time_point messageTime, string_view svFile, string_view svFunction, int nLine, string_view svMessage)
Format sStorage using qx::logger_specifiers.
compile_pattern_result compile_pattern(basic_string< char_t, traits_t > &sPattern) noexcept
Compile an fmt pattern with named arguments into replacement fields.