Apache Log4cxx  Version 1.6.0
Loading...
Searching...
No Matches
asyncbuffer.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef LOG4CXX_ASYNC_BUFFER_H
19#define LOG4CXX_ASYNC_BUFFER_H
20
22#include <functional>
23#include <vector>
24#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
25#include <fmt/args.h>
26#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
27#include <fmt/xchar.h>
28#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
29#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
30#if defined(__cpp_concepts) && 202002 <= __cpp_concepts
31#include <concepts>
32#endif
33
34namespace LOG4CXX_NS
35{
36
37namespace helpers
38{
39
45class LOG4CXX_EXPORT AsyncBuffer
46{
47public: // ...structors
51
55
59
60public: // Operators
65 template <typename T>
66 AsyncBuffer& operator<<(const T& value)
67 {
68#if defined(__cpp_concepts) && 202002 <= __cpp_concepts
69#if LOG4CXX_LOGCHAR_IS_UTF8
70 if constexpr (requires(std::ostream& buf, T v) { buf << v; })
71 {
72 append([value](CharMessageBuffer& msgBuf)
73 {
74 msgBuf << value;
75 });
76 }
77#if LOG4CXX_WCHAR_T_API
78 else if constexpr (requires(std::wostream& buf, T v) { buf << v; })
79 {
80 append([value](WideMessageBuffer& msgBuf)
81 {
82 msgBuf << value;
83 });
84 }
85#endif // LOG4CXX_WCHAR_T_API
86 else
87 static_assert(false, "operator<<(std::ostream&) overload must be provided");
88#else // !LOG4CXX_LOGCHAR_IS_UTF8
89 if constexpr (requires(std::wostream& buf, T v) { buf << v; })
90 {
91 append([value](WideMessageBuffer& msgBuf)
92 {
93 msgBuf << value;
94 });
95 }
96 else if constexpr (requires(std::ostream& buf, T v) { buf << v; })
97 {
98 append([value](CharMessageBuffer& msgBuf)
99 {
100 msgBuf << value;
101 });
102 }
103 else
104 static_assert(false, "operator<<(std::wostream&) overload must be provided");
105#endif // !LOG4CXX_LOGCHAR_IS_UTF8
106#else // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
107 append([value](LogCharMessageBuffer& msgBuf)
108 {
109 msgBuf << value;
110 });
111#endif // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
112 return *this;
113 }
114
115#ifdef __cpp_init_captures // C++ >= 14
120 template <typename T>
121 AsyncBuffer& operator<<(const T&& rvalue)
122 {
123#if defined(__cpp_concepts) && 202002 <= __cpp_concepts
124#if LOG4CXX_LOGCHAR_IS_UTF8
125 if constexpr (requires(std::ostream& buf, T v) { buf << v; })
126 {
127 append([value = std::move(rvalue)](CharMessageBuffer& msgBuf)
128 {
129 msgBuf << value;
130 });
131 }
132#if LOG4CXX_WCHAR_T_API
133 else if constexpr (requires(std::wostream& buf, T v) { buf << v; })
134 {
135 append([value = std::move(rvalue)](WideMessageBuffer& msgBuf)
136 {
137 msgBuf << value;
138 });
139 }
140#endif // LOG4CXX_WCHAR_T_API
141 else
142 static_assert(false, "operator<<(std::ostream&) overload must be provided");
143#else // !LOG4CXX_LOGCHAR_IS_UTF8
144 if constexpr (requires(std::wostream& buf, T v) { buf << v; })
145 {
146 append([value = std::move(rvalue)](WideMessageBuffer& msgBuf)
147 {
148 msgBuf << value;
149 });
150 }
151 else if constexpr (requires(std::ostream& buf, T v) { buf << v; })
152 {
153 append([value = std::move(rvalue)](CharMessageBuffer& msgBuf)
154 {
155 msgBuf << value;
156 });
157 }
158 else
159 static_assert(false, "operator<<(std::wostream&) overload must be provided");
160#endif // !LOG4CXX_LOGCHAR_IS_UTF8
161#else // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
162 append([value = std::move(rvalue)](LogCharMessageBuffer& msgBuf)
163 {
164 msgBuf << value;
165 });
166#endif // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
167 return *this;
168 }
169
170#endif // __cpp_init_captures
171
172public: // Accessors
176 bool empty() const;
177
181 void renderMessage(LogCharMessageBuffer& msg) const;
182
183public: // Modifiers
187 void clear();
188
189#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
190 using StringViewType = fmt::basic_string_view<char>;
191 using FmtArgStore = fmt::dynamic_format_arg_store<fmt::format_context>;
192 template <typename... Args>
193 void setMessage(fmt::format_string<Args...> fmt_str, Args&&... args)
194 {
195 auto store = FmtArgStore();
196 ( store.push_back(std::forward<Args>(args)), ...);
197 initializeForFmt(std::move(fmt_str), std::move(store));
198 }
199
200#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
201 using WideStringViewType = fmt::basic_string_view<wchar_t>;
202 using WideFmtArgStore = fmt::dynamic_format_arg_store<fmt::wformat_context>;
203 template <typename... Args>
204 void setMessage(fmt::wformat_string<Args...> fmt_str, Args&&... args)
205 {
206 auto store = WideFmtArgStore();
207 ( store.push_back(std::forward<Args>(args)), ...);
208 initializeForFmt(std::move(fmt_str), std::move(store));
209 }
210#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
211#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
212
213private:
214 AsyncBuffer(const AsyncBuffer&) = delete;
215 AsyncBuffer& operator=(const AsyncBuffer&) = delete;
216
217 LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(Private, m_priv)
218#if defined(__cpp_concepts) && 202002 <= __cpp_concepts
219 using MessageBufferAppender = std::function<void(CharMessageBuffer&)>;
220
224 void append(const MessageBufferAppender& f);
225
226#if LOG4CXX_WCHAR_T_API
227 using WideMessageBufferAppender = std::function<void(WideMessageBuffer&)>;
228
232 void append(const WideMessageBufferAppender& f);
233#endif // LOG4CXX_WCHAR_T_API
234#else // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
235 using MessageBufferAppender = std::function<void(LogCharMessageBuffer&)>;
236
240 void append(const MessageBufferAppender& f);
241#endif // !(defined(__cpp_concepts) && 202002 <= __cpp_concepts)
242
243#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
244 void initializeForFmt(StringViewType&& format_string, FmtArgStore&& args);
245
246#if LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
247 void initializeForFmt(WideStringViewType&& format_string, WideFmtArgStore&& args);
248#endif // LOG4CXX_WCHAR_T_API || LOG4CXX_LOGCHAR_IS_WCHAR
249#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
250};
251
252} // namespace helpers
253} // namespace LOG4CXX_NS
254
258
259#if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 10000
279#define LOG4CXX_DEBUG_ASYNC(logger, message) do { \
280 if (LOG4CXX_UNLIKELY(::LOG4CXX_NS::Logger::isDebugEnabledFor(logger))) {\
281 ::LOG4CXX_NS::helpers::AsyncBuffer buf; \
282 logger->addDebugEvent(std::move(buf << message), LOG4CXX_LOCATION); }} while (0)
283
284#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
304#define LOG4CXX_DEBUG_FMT_ASYNC(logger, fmt, ...) do { \
305 if (LOG4CXX_UNLIKELY(::LOG4CXX_NS::Logger::isDebugEnabledFor(logger))) {\
306 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
307 buf.setMessage(fmt LOG4CXX_FMT_VA_ARG(__VA_ARGS__));\
308 logger->addDebugEvent(std::move(buf), LOG4CXX_LOCATION); }} while (0)
309#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
310#else
311#define LOG4CXX_DEBUG_ASYNC(logger, message)
312#define LOG4CXX_DEBUG_FMT_ASYNC(logger, message)
313#endif
314
315#if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 5000
327#define LOG4CXX_TRACE_ASYNC(logger, message) do { \
328 if (LOG4CXX_UNLIKELY(::LOG4CXX_NS::Logger::isTraceEnabledFor(logger))) {\
329 ::LOG4CXX_NS::helpers::AsyncBuffer buf; \
330 logger->addTraceEvent(std::move(buf << message), LOG4CXX_LOCATION); }} while (0)
331
332#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
345#define LOG4CXX_TRACE_FMT_ASYNC(logger, fmt, ...) do { \
346 if (LOG4CXX_UNLIKELY(::LOG4CXX_NS::Logger::isTraceEnabledFor(logger))) {\
347 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
348 buf.setMessage(fmt LOG4CXX_FMT_VA_ARG(__VA_ARGS__));\
349 logger->addTraceEvent(std::move(buf), LOG4CXX_LOCATION); }} while (0)
350#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
351
352#else
353#define LOG4CXX_TRACE_ASYNC(logger, message)
354#define LOG4CXX_TRACE_FMT_ASYNC(logger, message)
355#endif
356
357#if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 20000
374#define LOG4CXX_INFO_ASYNC(logger, message) do { \
375 if (::LOG4CXX_NS::Logger::isInfoEnabledFor(logger)) {\
376 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
377 logger->addInfoEvent(std::move(buf << message), LOG4CXX_LOCATION);\
378 }} while (0)
379
380#endif
381
382#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
399#define LOG4CXX_INFO_FMT_ASYNC(logger, fmt, ...) do { \
400 if (::LOG4CXX_NS::Logger::isInfoEnabledFor(logger)) {\
401 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
402 buf.setMessage(fmt LOG4CXX_FMT_VA_ARG(__VA_ARGS__));\
403 logger->addInfoEvent(std::move(buf), LOG4CXX_LOCATION); }} while (0)
404#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
405
406#else
407#define LOG4CXX_INFO_ASYNC(logger, message)
408#define LOG4CXX_INFO_FMT_ASYNC(logger, message)
409#endif
410
411#if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 30000
426#define LOG4CXX_WARN_ASYNC(logger, message) do { \
427 if (::LOG4CXX_NS::Logger::isWarnEnabledFor(logger)) {\
428 ::LOG4CXX_NS::helpers::AsyncBuffer buf; \
429 logger->addWarnEvent(std::move(buf << message), LOG4CXX_LOCATION); }} while (0)
430
431#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
447#define LOG4CXX_WARN_FMT_ASYNC(logger, fmt, ...) do { \
448 if (::LOG4CXX_NS::Logger::isWarnEnabledFor(logger)) {\
449 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
450 buf.setMessage(fmt LOG4CXX_FMT_VA_ARG(__VA_ARGS__));\
451 logger->addWarnEvent(std::move(buf), LOG4CXX_LOCATION); }} while (0)
452#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
453
454#else
455#define LOG4CXX_WARN_ASYNC(logger, message)
456#define LOG4CXX_WARN_FMT_ASYNC(logger, message)
457#endif
458
459#if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 40000
474#define LOG4CXX_ERROR_ASYNC(logger, message) do { \
475 if (::LOG4CXX_NS::Logger::isErrorEnabledFor(logger)) {\
476 ::LOG4CXX_NS::helpers::AsyncBuffer buf; \
477 logger->addErrorEvent(std::move(buf << message), LOG4CXX_LOCATION); }} while (0)
478
479#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
495#define LOG4CXX_ERROR_FMT_ASYNC(logger, fmt, ...) do { \
496 if (::LOG4CXX_NS::Logger::isErrorEnabledFor(logger)) {\
497 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
498 buf.setMessage(fmt LOG4CXX_FMT_VA_ARG(__VA_ARGS__));\
499 logger->addErrorEvent(std::move(buf), LOG4CXX_LOCATION); }} while (0)
500#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
501
509#define LOG4CXX_ASSERT_ASYNC(logger, condition, message) do { \
510 if (!(condition) && ::LOG4CXX_NS::Logger::isErrorEnabledFor(logger)) {\
511 ::LOG4CXX_NS::helpers::AsyncBuffer buf; \
512 LOG4CXX_STACKTRACE \
513 logger->addErrorEvent(std::move(buf << message), LOG4CXX_LOCATION); }} while (0)
514
515#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
526#define LOG4CXX_ASSERT_FMT_ASYNC(logger, condition, fmt, ...) do { \
527 if (!(condition) && ::LOG4CXX_NS::Logger::isErrorEnabledFor(logger)) {\
528 LOG4CXX_STACKTRACE \
529 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
530 buf.setMessage(fmt LOG4CXX_FMT_VA_ARG(__VA_ARGS__));\
531 logger->addErrorEvent(std::move(buf), LOG4CXX_LOCATION); }} while (0)
532#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
533
534#else
535#define LOG4CXX_ERROR_ASYNC(logger, message)
536#define LOG4CXX_ERROR_FMT_ASYNC(logger, message)
537#define LOG4CXX_ASSERT_ASYNC(logger, condition, message)
538#define LOG4CXX_ASSERT_FMT_ASYNC(logger, condition, message)
539#endif
540
541#if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 50000
553#define LOG4CXX_FATAL_ASYNC(logger, message) do { \
554 if (::LOG4CXX_NS::Logger::isFatalEnabledFor(logger)) {\
555 ::LOG4CXX_NS::helpers::AsyncBuffer buf; \
556 logger->addFatalEvent(std::move(buf << message), LOG4CXX_LOCATION); }} while (0)
557
558#if LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
571#define LOG4CXX_FATAL_FMT_ASYNC(logger, fmt, ...) do { \
572 if (::LOG4CXX_NS::Logger::isFatalEnabledFor(logger)) {\
573 ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
574 buf.setMessage(fmt LOG4CXX_FMT_VA_ARG(__VA_ARGS__));\
575 logger->addFatalEvent(std::move(buf), LOG4CXX_LOCATION); }} while (0)
576#endif // LOG4CXX_ASYNC_BUFFER_SUPPORTS_FMT
577
578#else
579#define LOG4CXX_FATAL_ASYNC(logger, message)
580#define LOG4CXX_FATAL_FMT_ASYNC(logger, message)
581#endif
582
This class is used by the LOG4CXX_INFO_ASYNC and similar macros to support insertion operators.
Definition asyncbuffer.h:46
bool empty() const
Has no item been added to this?
fmt::dynamic_format_arg_store< fmt::format_context > FmtArgStore
Definition asyncbuffer.h:191
~AsyncBuffer()
Release resources.
fmt::basic_string_view< wchar_t > WideStringViewType
Definition asyncbuffer.h:201
fmt::dynamic_format_arg_store< fmt::wformat_context > WideFmtArgStore
Definition asyncbuffer.h:202
AsyncBuffer(AsyncBuffer &&other)
A new buffer with the content of other.
void setMessage(fmt::format_string< Args... > fmt_str, Args &&... args)
Definition asyncbuffer.h:193
void renderMessage(LogCharMessageBuffer &msg) const
Add text version of buffered values to msg.
AsyncBuffer()
An empty buffer.
void setMessage(fmt::wformat_string< Args... > fmt_str, Args &&... args)
Definition asyncbuffer.h:204
AsyncBuffer & operator<<(const T &value)
Append a function to this buffer that will convert value to text.
Definition asyncbuffer.h:66
void clear()
Remove all message appenders.
fmt::basic_string_view< char > StringViewType
Definition asyncbuffer.h:190
This class is used by the LOG4CXX_INFO and similar macros to support insertion operators in the messa...
Definition log4cxx/helpers/messagebuffer.h:40
This class is designed to support insertion operations in the message argument to the LOG4CXX_INFO an...
Definition log4cxx/helpers/messagebuffer.h:405
log4cxx::helpers::UniCharMessageBuffer & operator<<(log4cxx::helpers::UniCharMessageBuffer &mb, const QString &msg)
Definition log4cxx-qt/messagebuffer.h:24