24 string_view svFunction,
26 string_view swLogMessage)
34 std::lock_guard lock(m_LoggerStreamMutex);
39 auto formatFunc = optLogUnit->pUnitInfo->formatFunc;
47 string_view svFunction,
49 string_view swLogMessage)
56 QX_PERF_SCOPE(
"Log formatting");
57 formatFunc(buffers, eVerbosity,
category, svFile, svFunction, nLine, swLogMessage);
60 if (!buffers.sMessage.empty())
62 do_log(buffers.sMessage, *optLogUnit, buffers.colors, eVerbosity);
70 if (!svUnitName.empty())
83 string_view svFunction)
const noexcept
87 auto find_unit = [
this](string_view svUnit)
89 return !svUnit.empty() ? m_Units.find(
string_hash(svUnit)) : m_Units.cend();
92 std::optional<log_unit> optLogUnit = std::nullopt;
96 else if (it = find_unit(svFile); it != m_Units.cend())
97 optLogUnit = { &it->second, svFile };
98 else if (it = find_unit(svFunction); it != m_Units.cend())
99 optLogUnit = { &it->second, svFunction };
100 else if (it = find_unit(k_svDefaultUnit); it != m_Units.cend())
101 optLogUnit = { &it->second, k_svDefaultUnit };
103 if (optLogUnit && optLogUnit->pUnitInfo && eVerbosity >= optLogUnit->pUnitInfo->eMinVerbosity)
111 char_type chDateDelimiter,
112 char_type chTimeDelimiter) noexcept
114 std::time_t t = std::time(
nullptr);
115 QX_PUSH_SUPPRESS_MSVC_WARNINGS(4996);
116 std::tm* now = std::localtime(&t);
117 QX_POP_SUPPRESS_WARNINGS();
120 QX_TEXT(
"{:02}{}{:02}{}{:04}_{:02}{}{:02}{}{:02}"),
140 verbosity eVerbosity,
143 string_view svFunction,
145 string_view swLogMessage) noexcept
149 case verbosity::very_verbose:
150 buffers.sMessage = QX_TEXT(
"[VV][");
153 case verbosity::verbose:
154 buffers.sMessage = QX_TEXT(
"[V][");
157 case verbosity::important:
158 buffers.sMessage = QX_TEXT(
"[I][");
161 case verbosity::warning:
162 buffers.sMessage = QX_TEXT(
"[W][");
165 case verbosity::error:
166 buffers.sMessage = QX_TEXT(
"[E][");
169 case verbosity::critical:
170 buffers.sMessage = QX_TEXT(
"[C][");
174 buffers.sMessage = QX_TEXT(
" [");
178 append_time_string(buffers.sMessage, QX_TEXT(
'.'), QX_TEXT(
':'));
179 buffers.sMessage += QX_TEXT(
"][");
182 if (!svCategory.empty())
184 buffers.sMessage += svCategory;
185 buffers.sMessage += QX_TEXT(
"][");
188 buffers.sMessage.append_format(QX_TEXT(
"{}::{}::{}] {}\n"), svFile, svFunction, nLine, swLogMessage);
190 if (!svCategory.empty())
191 if (
auto nPos = buffers.sMessage.find(svCategory); nPos != string::npos)
192 buffers.colors.push_back({ { nPos, nPos + svCategory.size() },
category.
get_color() });
#define QX_DEFINE_FILE_CATEGORY(_category)
Define file category You can access this value via QX_FILE_CATEGORY() This category will not be expor...
static void append_time_string(string &sTime, char_type chDateDelimiter, char_type chTimeDelimiter) noexcept
Format time string to the buffer.
void log(verbosity eVerbosity, const category &category, string_view svFile, string_view svFunction, int nLine, string_view swLogMessage)
Output to stream.
std::optional< log_unit > get_unit_info(const category &category, verbosity eVerbosity, string_view svFile, string_view svFunction) const noexcept
Try to find log unit info based on trace location info.
logger_buffer & get_log_buffer() noexcept
Get string buffers.
virtual void flush()=0
Flush stream.
void deregister_unit(string_view svUnitName) noexcept
Deregister logger unit.
base_logger_stream(bool bAlwaysFlush)
base_logger_stream object constructor
void register_unit(string_view svUnitName, const log_unit_info &unit) noexcept
Register logger unit.
virtual void format_line(logger_buffer &buffers, verbosity eVerbosity, const category &category, string_view svFile, string_view svFunction, int nLine, string_view swLogMessage) noexcept
Format logger line.
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.
constexpr const color & get_color() const noexcept
Get category color.