quill
LogFunctions.h
1 
7 #pragma once
8 
9 #include "quill/core/Attributes.h"
10 #include "quill/core/Common.h"
11 #include "quill/core/LogLevel.h"
12 #include "quill/core/MacroMetadata.h"
13 #include "quill/core/SourceLocation.h"
14 
15 #include <string>
16 #include <type_traits>
17 #include <utility>
18 
19 QUILL_BEGIN_NAMESPACE
20 
21 QUILL_BEGIN_EXPORT
22 
55 struct Tags
56 {
57  Tags() = default;
58 
63  explicit Tags(char const* tag)
64  {
65  append_tag(tag);
66  _append_trailing_space_if_needed();
67  }
68 
75  template <typename... RestTags>
76  Tags(char const* first_tag, char const* second_tag, RestTags... rest_tags)
77  {
78  static_assert(std::conjunction_v<std::is_same<char const*, RestTags>...>,
79  "All tag parameters must be of type 'char const*'");
80 
81  append_tag(first_tag);
82  append_tag(second_tag);
83  (append_tag(rest_tags), ...);
84  _append_trailing_space_if_needed();
85  }
86 
87  // Get the combined tags string
88  QUILL_NODISCARD char const* value() const noexcept { return _value.c_str(); }
89 
90 private:
91  std::string _value;
92 
93  void append_tag(char const* tag)
94  {
95  if (QUILL_UNLIKELY(!tag))
96  {
97  return;
98  }
99 
100  if (!_value.empty())
101  {
102  _value += " #";
103  }
104  else
105  {
106  _value += '#';
107  }
108 
109  _value += tag;
110  }
111 
112  void _append_trailing_space_if_needed()
113  {
114  if (!_value.empty())
115  {
116  _value += ' ';
117  }
118  }
119 };
120 
121 template <typename TLogger, typename... Args>
122 struct tracel3
123 {
124  tracel3(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
125  {
126  log(logger, "", LogLevel::TraceL3, fmt, location, std::forward<Args>(args)...);
127  }
128 
129  tracel3(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
130  SourceLocation location = SourceLocation::current())
131  {
132  log(logger, tags.value(), LogLevel::TraceL3, fmt, location, std::forward<Args>(args)...);
133  }
134 };
135 
136 template <typename TLogger, typename... Args>
137 tracel3(TLogger*, char const*, Args&&...) -> tracel3<TLogger, Args...>;
138 
139 template <typename TLogger, typename... Args>
140 tracel3(TLogger*, Tags const& tags, char const*, Args&&...) -> tracel3<TLogger, Args...>;
141 
142 template <typename TLogger, typename... Args>
143 struct tracel2
144 {
145  tracel2(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
146  {
147  log(logger, "", LogLevel::TraceL2, fmt, location, std::forward<Args>(args)...);
148  }
149 
150  tracel2(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
151  SourceLocation location = SourceLocation::current())
152  {
153  log(logger, tags.value(), LogLevel::TraceL2, fmt, location, std::forward<Args>(args)...);
154  }
155 };
156 
157 template <typename TLogger, typename... Args>
158 tracel2(TLogger*, char const*, Args&&...) -> tracel2<TLogger, Args...>;
159 
160 template <typename TLogger, typename... Args>
161 tracel2(TLogger*, Tags const& tags, char const*, Args&&...) -> tracel2<TLogger, Args...>;
162 
163 template <typename TLogger, typename... Args>
164 struct tracel1
165 {
166  tracel1(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
167  {
168  log(logger, "", LogLevel::TraceL1, fmt, location, std::forward<Args>(args)...);
169  }
170 
171  tracel1(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
172  SourceLocation location = SourceLocation::current())
173  {
174  log(logger, tags.value(), LogLevel::TraceL1, fmt, location, std::forward<Args>(args)...);
175  }
176 };
177 
178 template <typename TLogger, typename... Args>
179 tracel1(TLogger*, char const*, Args&&...) -> tracel1<TLogger, Args...>;
180 
181 template <typename TLogger, typename... Args>
182 tracel1(TLogger*, Tags const& tags, char const*, Args&&...) -> tracel1<TLogger, Args...>;
183 
184 template <typename TLogger, typename... Args>
185 struct debug
186 {
187  debug(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
188  {
189  log(logger, "", LogLevel::Debug, fmt, location, std::forward<Args>(args)...);
190  }
191 
192  debug(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
193  SourceLocation location = SourceLocation::current())
194  {
195  log(logger, tags.value(), LogLevel::Debug, fmt, location, std::forward<Args>(args)...);
196  }
197 };
198 
199 template <typename TLogger, typename... Args>
200 debug(TLogger*, char const*, Args&&...) -> debug<TLogger, Args...>;
201 
202 template <typename TLogger, typename... Args>
203 debug(TLogger*, Tags const& tags, char const*, Args&&...) -> debug<TLogger, Args...>;
204 
205 template <typename TLogger, typename... Args>
206 struct info
207 {
208  info(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
209  {
210  log(logger, "", LogLevel::Info, fmt, location, std::forward<Args>(args)...);
211  }
212 
213  info(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
214  SourceLocation location = SourceLocation::current())
215  {
216  log(logger, tags.value(), LogLevel::Info, fmt, location, std::forward<Args>(args)...);
217  }
218 };
219 
220 template <typename TLogger, typename... Args>
221 info(TLogger*, char const*, Args&&...) -> info<TLogger, Args...>;
222 
223 template <typename TLogger, typename... Args>
224 info(TLogger*, Tags const& tags, char const*, Args&&...) -> info<TLogger, Args...>;
225 
226 template <typename TLogger, typename... Args>
227 struct notice
228 {
229  notice(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
230  {
231  log(logger, "", LogLevel::Notice, fmt, location, std::forward<Args>(args)...);
232  }
233 
234  notice(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
235  SourceLocation location = SourceLocation::current())
236  {
237  log(logger, tags.value(), LogLevel::Notice, fmt, location, std::forward<Args>(args)...);
238  }
239 };
240 
241 template <typename TLogger, typename... Args>
242 notice(TLogger*, char const*, Args&&...) -> notice<TLogger, Args...>;
243 
244 template <typename TLogger, typename... Args>
245 notice(TLogger*, Tags const& tags, char const*, Args&&...) -> notice<TLogger, Args...>;
246 
247 template <typename TLogger, typename... Args>
248 struct warning
249 {
250  warning(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
251  {
252  log(logger, "", LogLevel::Warning, fmt, location, std::forward<Args>(args)...);
253  }
254 
255  warning(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
256  SourceLocation location = SourceLocation::current())
257  {
258  log(logger, tags.value(), LogLevel::Warning, fmt, location, std::forward<Args>(args)...);
259  }
260 };
261 
262 template <typename TLogger, typename... Args>
263 warning(TLogger*, char const*, Args&&...) -> warning<TLogger, Args...>;
264 
265 template <typename TLogger, typename... Args>
266 warning(TLogger*, Tags const& tags, char const*, Args&&...) -> warning<TLogger, Args...>;
267 
268 template <typename TLogger, typename... Args>
269 struct error
270 {
271  error(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
272  {
273  log(logger, "", LogLevel::Error, fmt, location, std::forward<Args>(args)...);
274  }
275 
276  error(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
277  SourceLocation location = SourceLocation::current())
278  {
279  log(logger, tags.value(), LogLevel::Error, fmt, location, std::forward<Args>(args)...);
280  }
281 };
282 
283 template <typename TLogger, typename... Args>
284 error(TLogger*, char const*, Args&&...) -> error<TLogger, Args...>;
285 
286 template <typename TLogger, typename... Args>
287 error(TLogger*, Tags const& tags, char const*, Args&&...) -> error<TLogger, Args...>;
288 
289 template <typename TLogger, typename... Args>
290 struct critical
291 {
292  critical(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
293  {
294  log(logger, "", LogLevel::Critical, fmt, location, std::forward<Args>(args)...);
295  }
296 
297  critical(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
298  SourceLocation location = SourceLocation::current())
299  {
300  log(logger, tags.value(), LogLevel::Critical, fmt, location, std::forward<Args>(args)...);
301  }
302 };
303 
304 template <typename TLogger, typename... Args>
305 critical(TLogger*, char const*, Args&&...) -> critical<TLogger, Args...>;
306 
307 template <typename TLogger, typename... Args>
308 critical(TLogger*, Tags const& tags, char const*, Args&&...) -> critical<TLogger, Args...>;
309 
310 template <typename TLogger, typename... Args>
311 struct backtrace
312 {
313  backtrace(TLogger* logger, char const* fmt, Args&&... args, SourceLocation location = SourceLocation::current())
314  {
315  log(logger, "", LogLevel::Backtrace, fmt, location, std::forward<Args>(args)...);
316  }
317 
318  backtrace(TLogger* logger, Tags const& tags, char const* fmt, Args&&... args,
319  SourceLocation location = SourceLocation::current())
320  {
321  log(logger, tags.value(), LogLevel::Backtrace, fmt, location, std::forward<Args>(args)...);
322  }
323 };
324 
325 template <typename TLogger, typename... Args>
326 backtrace(TLogger*, char const*, Args&&...) -> backtrace<TLogger, Args...>;
327 
328 template <typename TLogger, typename... Args>
329 backtrace(TLogger*, Tags const& tags, char const*, Args&&...) -> backtrace<TLogger, Args...>;
330 
331 /***/
332 template <typename TLogger, typename... Args>
333 QUILL_ATTRIBUTE_HOT void log(TLogger* logger, char const* tags, LogLevel log_level, char const* fmt,
334  SourceLocation const& location, Args&&... args)
335 {
336  if (QUILL_UNLIKELY(!logger))
337  {
338  return;
339  }
340 
341  static constexpr MacroMetadata macro_metadata{
342  "[placeholder]", "[placeholder]", "[placeholder]",
343  nullptr, LogLevel::None, MacroMetadata::Event::LogWithRuntimeMetadataHybridCopy};
344 
345  if (logger->should_log_statement(log_level))
346  {
347  logger->template log_statement_runtime_metadata<true>(
348  &macro_metadata, fmt, location.file_name(), location.function_name(), tags, location.line(),
349  log_level, std::forward<Args>(args)...);
350  }
351 }
352 
353 QUILL_END_EXPORT
354 
355 QUILL_END_NAMESPACE
Definition: LogFunctions.h:143
Definition: LogFunctions.h:227
Definition: LogFunctions.h:206
Captures and stores information about a logging event in compile time.
Definition: MacroMetadata.h:24
Tags(char const *tag)
Single tag constructor.
Definition: LogFunctions.h:63
Definition: LogFunctions.h:185
Definition: LogFunctions.h:269
Definition: LogFunctions.h:122
Definition: LogFunctions.h:248
Tags(char const *first_tag, char const *second_tag, RestTags... rest_tags)
Constructor for multiple tags.
Definition: LogFunctions.h:76
Definition: SourceLocation.h:40
Definition: LogFunctions.h:290
Definition: LogFunctions.h:164
Definition: LogFunctions.h:311
Macro-Free Logging Interface
Definition: LogFunctions.h:55