CppLogging  1.0.4.0
C++ Logging Library
record.inl
Go to the documentation of this file.
1 
9 namespace CppLogging {
10 
12  : timestamp(CppCommon::Timestamp::utc()),
13  thread(CppCommon::Thread::CurrentThreadId()),
14  level(Level::INFO)
15 {
16  logger.reserve(32);
17  message.reserve(512);
18  buffer.reserve(512);
19  raw.reserve(512);
20 }
21 
22 enum class ArgumentType : uint8_t
23 {
25  ARG_BOOL,
26  ARG_CHAR,
27  ARG_WCHAR,
28  ARG_INT8,
29  ARG_UINT8,
30  ARG_INT16,
31  ARG_UINT16,
32  ARG_INT32,
33  ARG_UINT32,
34  ARG_INT64,
35  ARG_UINT64,
36  ARG_FLOAT,
37  ARG_DOUBLE,
38  ARG_STRING,
41  ARG_CUSTOM,
42  ARG_LIST
43 };
44 
45 inline void SerializeArgument(Record& record)
46 {
47 }
48 
49 inline void SerializeArgument(Record& record, bool argument)
50 {
51  // Append the argument type
52  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_BOOL);
53 
54  uint8_t value = argument;
55 
56  // Append the argument value
57  size_t size = sizeof(value);
58  record.buffer.resize(record.buffer.size() + size);
59  std::memcpy(record.buffer.data() + record.buffer.size() - size, &value, size);
60 }
61 
62 inline void SerializeArgument(Record& record, char argument)
63 {
64  // Append the argument type
65  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_CHAR);
66 
67  uint8_t value = argument;
68 
69  // Append the argument value
70  size_t size = sizeof(value);
71  record.buffer.resize(record.buffer.size() + size);
72  std::memcpy(record.buffer.data() + record.buffer.size() - size, &value, size);
73 }
74 
75 inline void SerializeArgument(Record& record, wchar_t argument)
76 {
77  // Append the argument type
78  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_WCHAR);
79 
80  uint32_t value = argument;
81 
82  // Append the argument value
83  size_t size = sizeof(value);
84  record.buffer.resize(record.buffer.size() + size);
85  std::memcpy(record.buffer.data() + record.buffer.size() - size, &value, size);
86 }
87 
88 inline void SerializeArgument(Record& record, int8_t argument)
89 {
90  // Append the argument type
91  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_INT8);
92 
93  // Append the argument value
94  size_t size = sizeof(argument);
95  record.buffer.resize(record.buffer.size() + size);
96  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
97 }
98 
99 inline void SerializeArgument(Record& record, uint8_t argument)
100 {
101  // Append the argument type
102  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_UINT8);
103 
104  // Append the argument value
105  size_t size = sizeof(argument);
106  record.buffer.resize(record.buffer.size() + size);
107  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
108 }
109 
110 inline void SerializeArgument(Record& record, int16_t argument)
111 {
112  // Append the argument type
113  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_INT16);
114 
115  // Append the argument value
116  size_t size = sizeof(argument);
117  record.buffer.resize(record.buffer.size() + size);
118  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
119 
120 }
121 
122 inline void SerializeArgument(Record& record, uint16_t argument)
123 {
124  // Append the argument type
125  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_UINT16);
126 
127  // Append the argument value
128  size_t size = sizeof(argument);
129  record.buffer.resize(record.buffer.size() + size);
130  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
131 }
132 
133 inline void SerializeArgument(Record& record, int32_t argument)
134 {
135  // Append the argument type
136  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_INT32);
137 
138  // Append the argument value
139  size_t size = sizeof(argument);
140  record.buffer.resize(record.buffer.size() + size);
141  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
142 }
143 
144 inline void SerializeArgument(Record& record, uint32_t argument)
145 {
146  // Append the argument type
147  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_UINT32);
148 
149  // Append the argument value
150  size_t size = sizeof(argument);
151  record.buffer.resize(record.buffer.size() + size);
152  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
153 }
154 
155 inline void SerializeArgument(Record& record, int64_t argument)
156 {
157  // Append the argument type
158  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_INT64);
159 
160  // Append the argument value
161  size_t size = sizeof(argument);
162  record.buffer.resize(record.buffer.size() + size);
163  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
164 }
165 
166 inline void SerializeArgument(Record& record, uint64_t argument)
167 {
168  // Append the argument type
169  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_UINT64);
170 
171  // Append the argument value
172  size_t size = sizeof(argument);
173  record.buffer.resize(record.buffer.size() + size);
174  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
175 }
176 
177 #if defined(__APPLE__)
178 
179 // Workaround for MacOS issue with template specialization for size_t
180 // https://stackoverflow.com/questions/11603818/why-is-there-ambiguity-between-uint32-t-and-uint64-t-when-using-size-t-on-mac-os
181 inline void SerializeArgument(Record& record, size_t argument)
182 {
183  uint64_t arg = argument;
184 
185  // Append the argument type
186  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_UINT64);
187 
188  // Append the argument value
189  size_t size = sizeof(arg);
190  record.buffer.resize(record.buffer.size() + size);
191  std::memcpy(record.buffer.data() + record.buffer.size() - size, &arg, size);
192 }
193 
194 #endif
195 
196 inline void SerializeArgument(Record& record, float argument)
197 {
198  // Append the argument type
199  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_FLOAT);
200 
201  // Append the argument value
202  size_t size = sizeof(argument);
203  record.buffer.resize(record.buffer.size() + size);
204  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
205 }
206 
207 inline void SerializeArgument(Record& record, double argument)
208 {
209  // Append the argument type
210  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_DOUBLE);
211 
212  // Append the argument value
213  size_t size = sizeof(argument);
214  record.buffer.resize(record.buffer.size() + size);
215  std::memcpy(record.buffer.data() + record.buffer.size() - size, &argument, size);
216 }
217 
218 inline void SerializeArgument(Record& record, const char* argument)
219 {
220  // Append the argument type
221  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_STRING);
222 
223  uint32_t length = (uint32_t)std::strlen(argument);
224 
225  // Append the string length
226  size_t size = sizeof(length);
227  record.buffer.resize(record.buffer.size() + size);
228  std::memcpy(record.buffer.data() + record.buffer.size() - size, &length, size);
229 
230  // Append the string value
231  size = length;
232  record.buffer.resize(record.buffer.size() + size);
233  std::memcpy(record.buffer.data() + record.buffer.size() - size, argument, size);
234 }
235 
236 inline void SerializeArgument(Record& record, std::string_view argument)
237 {
238  // Append the argument type
239  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_STRING);
240 
241  uint32_t length = (uint32_t)argument.length();
242 
243  // Append the string length
244  size_t size = sizeof(length);
245  record.buffer.resize(record.buffer.size() + size);
246  std::memcpy(record.buffer.data() + record.buffer.size() - size, &length, size);
247 
248  // Append the string value
249  size = length;
250  record.buffer.resize(record.buffer.size() + size);
251  std::memcpy(record.buffer.data() + record.buffer.size() - size, argument.data(), size);
252 }
253 
254 inline void SerializeArgument(Record& record, const std::string& argument)
255 {
256  // Append the argument type
257  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_STRING);
258 
259  uint32_t length = (uint32_t)argument.length();
260 
261  // Append the string length
262  size_t size = sizeof(length);
263  record.buffer.resize(record.buffer.size() + size);
264  std::memcpy(record.buffer.data() + record.buffer.size() - size, &length, size);
265 
266  // Append the string value
267  size = length;
268  record.buffer.resize(record.buffer.size() + size);
269  std::memcpy(record.buffer.data() + record.buffer.size() - size, argument.data(), size);
270 }
271 
272 template <typename T>
273 inline void SerializeArgument(Record& record, T* argument)
274 {
275  // Append the argument type
276  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_POINTER);
277 
278  uint64_t value = (uint64_t)argument;
279 
280  // Append the pointer value
281  size_t size = sizeof(value);
282  record.buffer.resize(record.buffer.size() + size);
283  std::memcpy(record.buffer.data() + record.buffer.size() - size, &value, size);
284 }
285 
286 template <typename T>
287 inline void SerializeArgument(Record& record, const T* argument)
288 {
289  // Append the argument type
290  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_POINTER);
291 
292  uint64_t value = (uint64_t)argument;
293 
294  // Append the pointer value
295  size_t size = sizeof(value);
296  record.buffer.resize(record.buffer.size() + size);
297  std::memcpy(record.buffer.data() + record.buffer.size() - size, &value, size);
298 }
299 
300 template <typename T>
301 inline void SerializeArgument(Record& record, const fmt::detail::named_arg<char, T>& argument)
302 {
303  // Append the argument type
304  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_NAMEDARG);
305 
306  uint32_t length = (uint32_t)strlen(argument.name);
307 
308  // Append the argument name length
309  size_t size = sizeof(length);
310  record.buffer.resize(record.buffer.size() + size);
311  std::memcpy(record.buffer.data() + record.buffer.size() - size, &length, size);
312 
313  // Append the argument name value
314  size = length;
315  record.buffer.resize(record.buffer.size() + size);
316  std::memcpy(record.buffer.data() + record.buffer.size() - size, argument.name, size);
317 
318  SerializeArgument(record, argument.value);
319 }
320 
321 #if FMT_USE_NONTYPE_TEMPLATE_ARGS
322 
323 template <typename T, typename Char, size_t N, fmt::detail_exported::fixed_string<Char, N> Str>
324 inline void SerializeArgument(Record& record, const fmt::detail::statically_named_arg<T, Char, N, Str>& argument)
325 {
326  // Append the argument type
327  record.buffer.emplace_back((uint8_t)ArgumentType::ARG_NAMEDARG);
328 
329  uint32_t length = (uint32_t)strlen(argument.name);
330 
331  // Append the argument name length
332  size_t size = sizeof(length);
333  record.buffer.resize(record.buffer.size() + size);
334  std::memcpy(record.buffer.data() + record.buffer.size() - size, &length, size);
335 
336  // Append the argument name value
337  size = length;
338  record.buffer.resize(record.buffer.size() + size);
339  std::memcpy(record.buffer.data() + record.buffer.size() - size, argument.name, size);
340 
341  SerializeArgument(record, argument.value);
342 }
343 
344 #endif
345 
346 template <typename T>
347 inline void SerializeArgument(Record& record, const T& argument)
348 {
349  // Serialize the custom argument
350  record << argument;
351 }
352 
353 template <typename T, typename... Args>
354 inline void SerializeArgument(Record& record, const T& argument, Args&&... args)
355 {
356  SerializeArgument(record, argument);
357  SerializeArgument(record, std::forward<Args>(args)...);
358 }
359 
360 template <typename... T>
361 inline Record& Record::Format(fmt::format_string<T...> pattern, T&&... args)
362 {
363  message = CppCommon::format(pattern, std::forward<T>(args)...);
364  return *this;
365 }
366 
367 template <typename... T>
368 inline Record& Record::StoreFormat(fmt::format_string<T...> pattern, T&&... args)
369 {
370  fmt::string_view view = pattern;
371  message.assign(view.begin(), view.end());
372  SerializeArgument(*this, std::forward<T>(args)...);
373  return *this;
374 }
375 
376 template <typename Arg>
377 inline Record& Record::StoreCustom(const Arg& arg)
378 {
379  // Serialize argument
380  SerializeArgument(*this, arg);
381 
382  return *this;
383 }
384 
385 template <typename... Args>
386 inline Record& Record::StoreCustomFormat(std::string_view pattern, Args&&... args)
387 {
388  // Append the argument type
389  buffer.emplace_back((uint8_t)ArgumentType::ARG_CUSTOM);
390 
391  size_t offset = buffer.size();
392  buffer.resize(buffer.size() + sizeof(uint32_t));
393 
394  uint32_t length = (uint32_t)pattern.size();
395 
396  // Append the pattern length
397  size_t size = sizeof(length);
398  buffer.resize(buffer.size() + size);
399  std::memcpy(buffer.data() + buffer.size() - size, &length, size);
400 
401  // Append the pattern value
402  size = length;
403  buffer.resize(buffer.size() + size);
404  std::memcpy(buffer.data() + buffer.size() - size, pattern.data(), size);
405 
406  // Serialize arguments
407  SerializeArgument(*this, std::forward<Args>(args)...);
408 
409  size = buffer.size() - offset;
410  std::memcpy(buffer.data() + offset, &size, sizeof(uint32_t));
411 
412  return *this;
413 }
414 
415 inline size_t Record::StoreListBegin()
416 {
417  // Append the argument type
418  buffer.emplace_back((uint8_t)ArgumentType::ARG_LIST);
419 
420  size_t offset = buffer.size();
421  buffer.resize(buffer.size() + sizeof(uint32_t));
422 
423  return offset;
424 }
425 
426 template <typename... Args>
427 inline Record& Record::StoreList(Args&&... args)
428 {
429  // Serialize list arguments
430  SerializeArgument(*this, std::forward<Args>(args)...);
431 
432  return *this;
433 }
434 
435 template <typename... Args>
436 inline Record& Record::StoreListFormat(std::string_view pattern, Args&&... args)
437 {
438  return StoreCustomFormat(pattern, std::forward<Args>(args)...);
439 }
440 
441 inline Record& Record::StoreListEnd(size_t begin)
442 {
443  size_t size = buffer.size() - begin;
444  std::memcpy(buffer.data() + begin, &size, sizeof(uint32_t));
445 
446  return *this;
447 }
448 
449 inline void Record::Clear()
450 {
451  timestamp = 0;
452  thread = 0;
453  level = Level::NONE;
454  logger.clear();
455  message.clear();
456  buffer.clear();
457  raw.clear();
458 }
459 
460 inline void Record::swap(Record& record) noexcept
461 {
462  using std::swap;
463  swap(timestamp, record.timestamp);
464  swap(thread, record.thread);
465  swap(level, record.level);
466  swap(logger, record.logger);
467  swap(message, record.message);
468  swap(buffer, record.buffer);
469  swap(raw, record.raw);
470 }
471 
472 inline void swap(Record& record1, Record& record2) noexcept
473 {
474  record1.swap(record2);
475 }
476 
477 } // namespace CppLogging
Logging record.
Definition: record.h:37
void swap(Record &record) noexcept
Swap two instances.
Definition: record.inl:460
void Clear()
Clear logging record.
Definition: record.inl:449
Record & StoreListEnd(size_t begin)
Definition: record.inl:441
Level level
Level of the logging record.
Definition: record.h:44
std::vector< uint8_t > raw
Record content after layout.
Definition: record.h:53
std::string message
Message of the logging record.
Definition: record.h:48
Record & StoreCustomFormat(std::string_view pattern, Args &&... args)
Definition: record.inl:386
uint64_t thread
Thread Id of the logging record.
Definition: record.h:42
std::string logger
Logger name of the logging record.
Definition: record.h:46
std::vector< uint8_t > buffer
Buffer of the logging record.
Definition: record.h:50
Record & StoreListFormat(std::string_view pattern, Args &&... args)
Definition: record.inl:436
Record & StoreCustom(const Arg &arg)
Store custom format message and its arguments.
Definition: record.inl:377
size_t StoreListBegin()
Store list format message.
Definition: record.inl:415
Record & Format(fmt::format_string< T... > pattern, T &&... args)
Format message and its arguments.
Definition: record.inl:361
uint64_t timestamp
Timestamp of the logging record.
Definition: record.h:40
Record & StoreList(Args &&... args)
Definition: record.inl:427
Record & StoreFormat(fmt::format_string< T... > pattern, T &&... args)
Store format message and its arguments.
Definition: record.inl:368
C++ Logging project definitions.
Definition: appender.h:15
void swap(Record &record1, Record &record2) noexcept
Definition: record.inl:472
Level
Logging level.
Definition: level.h:18
@ INFO
Log information.
@ NONE
Log nothing.
void SerializeArgument(Record &record)
Definition: record.inl:45