farm-ng-core
logger.h
Go to the documentation of this file.
1 // Copyright 2022, farm-ng inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include "farm_ng/core/enum/enum.h"
19 
20 #include <farm_pp/preprocessor/comma.hpp>
21 #include <farm_pp/preprocessor/empty.hpp>
22 
23 #include <atomic>
24 #include <filesystem>
25 #include <unordered_set>
26 
27 namespace farm_ng {
28 FARM_ENUM(
29  LogLevel,
30  int,
31  ((trace, 0),
32  (debug, 1),
33  (info, 2),
34  (warning, 3),
35  (error, 4),
36  (critical, 5)));
37 
38 std::string stringFromLogLevel(LogLevel level);
39 
40 // A logger that writes to std::cerr
41 class StreamLogger {
42  public:
43  // The header format is a {fmt}-style format string that may include the
44  // named arguments {level}, {text}, {file}, {line}, {function}, {time}.
45  void setHeaderFormat(std::string const& str);
46  std::string getHeaderFormat() const;
47 
48  // Set the runtime log level
49  void setLogLevel(LogLevel level);
50  LogLevel getLogLevel();
51 
52  // A type-erased generator of timestamp strings
53  struct LogClock {
54  std::function<std::string()> now;
55  };
56 
57  // Set the clock used to produce timestamps
58  void setLogClock(LogClock log_clock);
59 
60  template <typename... TT>
61  inline void log(
62  LogLevel log_level,
63  std::string const& header_text,
64  std::string const& file,
65  int line,
66  std::string const& function,
67  std::string const& message,
68  TT&&... args) {
69  if (log_level_ <= LogLevel::warning &&
70  (log_level == LogLevel::debug || log_level == LogLevel::trace)) {
71  // We are already in compile-time enabled noisy log-level territory. Hence
72  // it is fine to do this hash map look-up from a performance standpoint.
73  if (noisy_modules_.find(file) == noisy_modules_.end()) {
74  // Only warn about noisy log level once per enabled compilation unit.
75  noisy_modules_.insert(file);
76  write("\n");
77  writeHeader(LogLevel::warning, header_text, file, line, function);
78  write(FARM_FORMAT(
79  "Noisy logging (DEBUG or TRACE) enabled for module: {} (runtime "
80  "log "
81  "level: {})",
82  file,
83  log_level_));
84  flush();
85  }
86  }
87 
88  if (log_level_ <= log_level) {
89  writeHeader(log_level, header_text, file, line, function);
90  write(FARM_FORMAT(message, std::forward<TT>(args)...));
91  flush();
92  }
93  }
94 
95  void log(
96  LogLevel log_level,
97  std::string const& header_text,
98  std::string const& file,
99  int line,
100  std::string const& function) {
101  this->log(log_level, header_text, file, line, function, std::string(""));
102  }
103 
104  private:
105  void writeHeader(
106  LogLevel log_level,
107  std::string const& header_text,
108  std::string const& file,
109  int line,
110  std::string const& function);
111  static void write(std::string const& str);
112  static void flush();
113 
114  static std::string const kDefaultHeaderFormat;
115  static LogLevel const kDefaultLogLevel = LogLevel(LogLevel::info);
116  static LogClock const kDefaultLogClock;
117 
118  std::string header_format_ = kDefaultHeaderFormat;
119  LogLevel log_level_ = kDefaultLogLevel;
120  LogClock log_clock_ = kDefaultLogClock;
121  std::unordered_set<std::string> noisy_modules_;
122 };
123 
125  static StreamLogger Static_Logger;
126  return Static_Logger;
127 }
128 
129 } // namespace farm_ng
130 
131 // Begin (Impl details)
132 #define FARM_VARGS(...) FARM_PP_COMMA() __VA_ARGS__
133 
134 #define FARM_VARGS_NONE(...)
135 
136 #define FARM_MAYBE_VARGS(...) \
137  FARM_PP_IF( \
138  FARM_PP_EQUAL(FARM_PP_VARIADIC_SIZE(dummy, ##__VA_ARGS__), 1), \
139  FARM_VARGS_NONE, \
140  FARM_VARGS)
141 
142 // Global toggle to enable logging, undefined to disable logging globally
143 #define FARM_LOG_ENABLED 1
144 
145 #ifdef FARM_LOG_ENABLED
146 /// Log level to be used for more noisy FYI type of status. Don't use FARM_INFO
147 /// if the pure compile-time invocation of the macro would hurt performance.
148 /// E.g. if this code might be executed within an inner loop such as for every
149 /// pixel of an image. Use FARM_DEBUG or FARM_TRACE instead which can be toggled
150 /// at compile-time (and are turned off by default).
151 #define FARM_INFO(...) \
152  farm_ng::defaultLogger().log( \
153  farm_ng::LogLevel::info, \
154  "INFO", \
155  __FILE__, \
156  __LINE__, \
157  __func__, \
158  __VA_ARGS__)
159 /// More significant information with high signal to noise. Typically to
160 /// communicate an usual but valid state of the program.
161 #define FARM_WARN(...) \
162  farm_ng::defaultLogger().log( \
163  farm_ng::LogLevel::warning, \
164  "WARN", \
165  __FILE__, \
166  __LINE__, \
167  __func__, \
168  __VA_ARGS__)
169 /// Error state (but not logical error/precondition violation nor panic).
170 /// Currently not used.
171 #define FARM_ERROR(...) \
172  farm_ng::defaultLogger().log( \
173  farm_ng::LogLevel::error, \
174  "ERROR", \
175  __FILE__, \
176  __LINE__, \
177  __func__, \
178  __VA_ARGS__)
179 /// Critical error state to communicated. Often followed by a panic (i.e.
180 /// std::abort, if enabled).
181 #define FARM_CRITICAL(...) \
182  farm_ng::defaultLogger().log( \
183  farm_ng::LogLevel::critical, \
184  "CRITICAL", \
185  __FILE__, \
186  __LINE__, \
187  __func__, \
188  __VA_ARGS__)
189 #else
190 #define FARM_INFO(...)
191 #define FARM_WARN(...)
192 #define FARM_ERROR(...)
193 #define FARM_CRITICAL(...)
194 #endif
195 
196 #define FARM_IMPL_ASSERT_OP(symbol, name_str, lhs, rhs, ...) \
197  do { \
198  if (!((lhs)symbol(rhs))) { \
199  farm_ng::defaultLogger().log( \
200  farm_ng::LogLevel::critical, \
201  FARM_FORMAT( \
202  "PANIC: ASSERT_{} failed\n Not true: {} {} {}\n{}\nvs.\n{}\n", \
203  name_str, \
204  #lhs, \
205  #symbol, \
206  #rhs, \
207  lhs, \
208  rhs), \
209  __FILE__, \
210  __LINE__, \
211  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
212  FARM_IMPL_ABORT(); \
213  } \
214  } while (false)
215 
216 // Deprecate
217 #define FARM_IMPL_LOG_HEADER(msg) \
218  FARM_IMPL_LOG_PRINTLN("[FARM {} in {}:{}]", msg, __FILE__, __LINE__)
219 
220 // End (Impl details)
221 
222 /// Print formatted error message and then panic.
223 #define FARM_PANIC(...) \
224  farm_ng::defaultLogger().log( \
225  farm_ng::LogLevel::critical, \
226  "PANIC!", \
227  __FILE__, \
228  __LINE__, \
229  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
230  FARM_IMPL_ABORT()
231 
232 /// Print formatted error message and then panic.
233 #define FARM_UNIMPLEMENTED(...) \
234  farm_ng::defaultLogger().log( \
235  farm_ng::LogLevel::critical, \
236  "PANIC: NOT IMPLEMENTED YET", \
237  __FILE__, \
238  __LINE__, \
239  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
240  FARM_IMPL_ABORT()
241 
242 // Deprecate
243 #define FARM_PRINTLN(cstr, ...) FARM_IMPL_LOG_PRINTLN(cstr, ##__VA_ARGS__)
244 
245 /// LOG INFO: Only log every nth encounter.
246 #define FARM_INFO_EVERY_N(N, ...) \
247  do { \
248  static std::atomic<int> counter(0); \
249  ++counter; \
250  if (counter > (N)) { \
251  counter -= (N); \
252  } \
253  if (counter == 1) { \
254  farm_ng::defaultLogger().log( \
255  farm_ng::LogLevel::info, \
256  FARM_FORMAT("LOG INFO EVERY N( = {} )", #N), \
257  __FILE__, \
258  __LINE__, \
259  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
260  } \
261  } while (false)
262 
263 /// If condition is false, Print formatted error message and then panic.
264 #define FARM_ASSERT(condition, ...) \
265  do { \
266  if (!(condition)) { \
267  farm_ng::defaultLogger().log( \
268  farm_ng::LogLevel::critical, \
269  FARM_FORMAT("PANIC: ASSERT failed\nbool({}) not true.", #condition), \
270  __FILE__, \
271  __LINE__, \
272  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
273  FARM_IMPL_ABORT(); \
274  } \
275  } while (false)
276 
277 /// If it is false that `lhs` == `rhs`, print formatted error message and then
278 /// panic.
279 #define FARM_ASSERT_EQ(lhs, rhs, ...) \
280  FARM_IMPL_ASSERT_OP(==, "EQ", lhs, rhs, __VA_ARGS__)
281 
282 /// If it is false that `lhs` != `rhs`, print formatted error message and then
283 /// panic.
284 #define FARM_ASSERT_NE(lhs, rhs, ...) \
285  FARM_IMPL_ASSERT_OP(!=, "NE", lhs, rhs, __VA_ARGS__)
286 
287 /// If it is false that `lhs` <= `rhs`, print formatted error message and then
288 /// panic.
289 #define FARM_ASSERT_LE(lhs, rhs, ...) \
290  FARM_IMPL_ASSERT_OP(<=, "LE", lhs, rhs, __VA_ARGS__)
291 
292 /// If it is false that `lhs` < `rhs`, print formatted error message and then
293 /// panic.
294 #define FARM_ASSERT_LT(lhs, rhs, ...) \
295  FARM_IMPL_ASSERT_OP(<, "LT", lhs, rhs, __VA_ARGS__)
296 
297 /// If it is false that `lhs` >= `rhs`, print formatted error message and then
298 /// panic.
299 #define FARM_ASSERT_GE(lhs, rhs, ...) \
300  FARM_IMPL_ASSERT_OP(>=, "GE", lhs, rhs, __VA_ARGS__)
301 
302 /// If it is false that `lhs` > `rhs`, print formatted error message and then
303 /// panic.
304 #define FARM_ASSERT_GT(lhs, rhs, ...) \
305  FARM_IMPL_ASSERT_OP(>, "GT", lhs, rhs, __VA_ARGS__)
306 
307 namespace farm_ng {
308 namespace details {
309 
310 template <class TPoint, class TEnabler = void>
311 struct CheckNear;
312 
313 template <class TT>
314 struct CheckNear<TT, std::enable_if_t<std::is_arithmetic_v<TT>, void>> {
315  static void impl(
316  double const& lhs,
317  double const& rhs,
318  double const& thr,
319  char const* lhs_cstr,
320  char const* rhs_cstr,
321  char const* thr_cstr,
322  std::string const& file,
323  int line,
324  std::string const& func,
325  std::string const& str) {
326  using std::abs;
327  using std::min;
328  auto lhs_abs = abs(lhs);
329  auto rhs_abs = abs(rhs);
330  if (min(lhs_abs, rhs_abs) < thr) {
331  /* close to zero, we are doing an absolute comparison*/
332  auto err = abs(lhs - rhs);
333  if (!(err < (thr))) {
335  farm_ng::LogLevel::critical,
336  FARM_FORMAT(
337  "ASSERT_NEAR absolute]\n"
338  "Not true: {} (={}) near {} (={}); has error of {} (thr: "
339  "{} (={}))",
340  lhs,
341  lhs_cstr,
342  rhs,
343  rhs_cstr,
344  err,
345  thr,
346  thr_cstr),
347  file,
348  line,
349  func,
350  str);
351  FARM_IMPL_ABORT();
352  }
353  } else {
354  /* relative comparison*/
355  double err = abs(lhs / rhs - 1.0);
356  if (!(err < (thr))) {
358  farm_ng::LogLevel::critical,
359  FARM_FORMAT(
360  "ASSERT_NEAR relative]\n"
361  "Not true: {} (={}) near {} (={}); has error of {} (thr: "
362  "{} (={}))",
363  lhs,
364  lhs_cstr,
365  rhs,
366  rhs_cstr,
367  err,
368  thr,
369  thr_cstr),
370  file,
371  line,
372  func,
373  str);
374  FARM_IMPL_ABORT();
375  }
376  }
377  }
378 };
379 
380 } // namespace details
381 } // namespace farm_ng
382 
383 /// If it is false that `lhs` is near `rhs` according to threshold `thr`, print
384 /// formatted error message and then panic.
385 ///
386 /// `lhs` and `rhs` are near, if maxMetric(lhs, rhs) < thr.
387 #define FARM_ASSERT_NEAR(lhs, rhs, thr, ...) \
388  ::farm_ng::details::CheckNear<std::decay_t<decltype(lhs)>>::impl( \
389  lhs, \
390  rhs, \
391  thr, \
392  #lhs, \
393  #rhs, \
394  #thr, \
395  __FILE__, \
396  __LINE__, \
397  __func__, \
398  FARM_FORMAT(__VA_ARGS__))
399 
400 namespace farm_ng {
401 struct ErrorDetail {
402  std::string file;
403  int line;
404  std::string msg;
405 };
406 
407 namespace details {
408 
409 template <class TContainer>
411  TContainer& container,
412  size_t index,
413  char const* container_cstr,
414  char const* index_cstr,
415  std::string const& file,
416  int line,
417  std::string const& func,
418  std::string const& str) -> decltype(container[index]) {
419  if (index >= container.size()) {
421  farm_ng::LogLevel::critical,
422  FARM_FORMAT(
423  "FARM_AT index `{}` (={}) not in contiguous container `{}` of size "
424  "`{}`",
425  index_cstr,
426  index,
427  container_cstr,
428  container.size()),
429  file,
430  line,
431  func,
432  str);
433  FARM_IMPL_ABORT();
434  }
435  return container[index];
436 }
437 
438 template <class TContainer, class TKey>
440  TContainer& container,
441  TKey const& key,
442  char const* container_cstr,
443  char const* key_cstr,
444  std::string const& file,
445  int line,
446  std::string const& func,
447  std::string const& str) -> decltype(*(container.find(key))) {
448  auto it = container.find(key);
449  if (it == container.end()) {
451  farm_ng::LogLevel::critical,
452  FARM_FORMAT(
453  "FARM_GET key `{}` (={}) not in associative container `{}` of size "
454  "`{}`",
455  key_cstr,
456  key,
457  container_cstr,
458  container.size()),
459  file,
460  line,
461  func,
462  str);
463  FARM_IMPL_ABORT();
464  }
465  return *it;
466 }
467 
468 template <class TMapLike, class TKey, class TValue>
470  TMapLike& map,
471  TKey const& key,
472  TValue const& value,
473  char const* container_cstr,
474  char const* key_cstr,
475  char const* value_cstr,
476  std::string const& file,
477  int line,
478  std::string const& func,
479  std::string const& str) {
480  auto const [iterator, success] = map.insert({key, value});
481 
482  if (!success) {
484  farm_ng::LogLevel::critical,
485  FARM_FORMAT(
486  "FARM_INSERT key `{}` (={}) is already in map `{}` of size `{}`.\n"
487  "We cannot insert value `{}`.",
488  key_cstr,
489  key,
490  container_cstr,
491  map.size(),
492  value_cstr),
493  file,
494  line,
495  func,
496  str);
497  FARM_IMPL_ABORT();
498  }
499  return iterator;
500 }
501 
502 template <class TWrapper>
503 struct UnwrapImpl {
504  static auto impl(
505  TWrapper& wrapper,
506  char const* wrapper_cstr,
507  ::farm_ng::ErrorDetail detail) -> decltype(*wrapper) {
508  if (!bool(wrapper)) {
510  farm_ng::LogLevel::critical,
511  FARM_FORMAT(
512  "FARM_UNWRAP wrapper type `{}` does not contain a valid value",
513  wrapper_cstr),
514  detail.file,
515  detail.line,
516  "",
517  detail.msg);
518  FARM_IMPL_ABORT();
519  }
520  return *wrapper;
521  }
522 };
523 
524 template <class TWrapper>
526  TWrapper& wrapper, char const* wrapper_cstr, ::farm_ng::ErrorDetail detail)
527  -> decltype(*wrapper) {
528  return UnwrapImpl<TWrapper>::impl(wrapper, wrapper_cstr, std::move(detail));
529 }
530 
531 } // namespace details
532 } // namespace farm_ng
533 
534 /// Returns `contiguous_container[index]`, but panics if `index` is out of
535 /// bounds.
536 #define FARM_AT(contiguous_container, index, ...) \
537  farm_ng::details::checkedAtContiguousContainer( \
538  contiguous_container, \
539  index, \
540  #contiguous_container, \
541  #index, \
542  __FILE__, \
543  __LINE__, \
544  __func__, \
545  FARM_FORMAT(__VA_ARGS__))
546 
547 /// Returns `associative_container[key]`, but panics if the container does not
548 /// contain `key` .
549 #define FARM_GET(associative_container, key, ...) \
550  farm_ng::details::checkedGetFromAssociativeContainer( \
551  associative_container, \
552  key, \
553  #associative_container, \
554  #key, \
555  __FILE__, \
556  __LINE__, \
557  __func__, \
558  FARM_FORMAT(__VA_ARGS__))
559 
560 /// Insert `val` to `map`, but panics if the container does
561 /// contain `key` already.
562 #define FARM_MAP_INSERT(map, key, value, ...) \
563  farm_ng::details::insertKeyValueInMap( \
564  map, \
565  key, \
566  value, \
567  #map, \
568  #key, \
569  #value, \
570  __FILE__, \
571  __LINE__, \
572  __func__, \
573  FARM_FORMAT(__VA_ARGS__))
574 
575 /// Returns `*wrapper`, but panics if `wrapper` is `nullopt` or `null`.
576 #define FARM_UNWRAP(wrapper, ...) \
577  farm_ng::details::unwrapImpl( \
578  wrapper, \
579  #wrapper, \
580  ::farm_ng::ErrorDetail{ \
581  .file = __FILE__, \
582  .line = __LINE__, \
583  .msg = FARM_FORMAT(__VA_ARGS__)})
584 
585 /// Asserts that the given path exits.
586 #define FARM_ASSERT_PATH_EXIST(path, ...) \
587  do { \
588  bool does_exist = std::filesystem::exists(path); \
589  if (!does_exist) { \
590  farm_ng::defaultLogger().log( \
591  farm_ng::LogLevel::critical, \
592  FARM_FORMAT( \
593  "PANIC: ASSERT_PATH_EXIST failed\nThe following path does not " \
594  "exist: {}", \
595  path), \
596  __FILE__, \
597  __LINE__, \
598  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
599  FARM_IMPL_ABORT(); \
600  } \
601  } while (false)
602 
603 /// Asserts that the given path is a regular file.
604 /// Hence it asserts that
605 /// a) it does exit,
606 /// b) it is a regular file.
607 #define FARM_ASSERT_IS_FILE(path, ...) \
608  do { \
609  FARM_ASSERT_PATH_EXIST(path); \
610  bool is_regular = std::filesystem::is_regular_file(path); \
611  if (!is_regular) { \
612  farm_ng::defaultLogger().log( \
613  farm_ng::LogLevel::critical, \
614  FARM_FORMAT( \
615  "PANIC: ASSERT_IS_FILE failed\nThe following path is not a " \
616  "regular file: {}", \
617  path), \
618  __FILE__, \
619  __LINE__, \
620  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
621  FARM_IMPL_ABORT(); \
622  } \
623  } while (false)
624 
625 /// Asserts that the given path is a folder.
626 /// Hence it asserts that
627 /// a) it does exit,
628 /// b) it is a folder (and not a file).
629 #define FARM_ASSERT_IS_FOLDER(path, ...) \
630  do { \
631  FARM_ASSERT_PATH_EXIST(path); \
632  bool is_folder = std::filesystem::is_directory(path); \
633  if (!is_folder) { \
634  farm_ng::defaultLogger().log( \
635  farm_ng::LogLevel::critical, \
636  FARM_FORMAT( \
637  "PANIC: ASSERT_IS_FOLDER failed\nThe following path is not a " \
638  "folder: {}", \
639  path), \
640  __FILE__, \
641  __LINE__, \
642  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
643  FARM_IMPL_ABORT(); \
644  } \
645  } while (false)
646 
647 /// Asserts that the given path is an empty folder.
648 /// Hence it asserts that
649 /// a) it does exit,
650 /// b) it is a folder (and not a file),
651 /// c) it is empty
652 #define FARM_ASSERT_FOLDER_IS_EMPTY(path, ...) \
653  do { \
654  FARM_ASSERT_IS_FOLDER(path); \
655  bool is_empty = std::filesystem::is_empty(path); \
656  if (!is_empty) { \
657  farm_ng::defaultLogger().log( \
658  farm_ng::LogLevel::critical, \
659  FARM_FORMAT( \
660  "PANIC: ASSERT_FOLDER_IS_EMPTY failed\nThe following folder is " \
661  "not empty: {}", \
662  path), \
663  __FILE__, \
664  __LINE__, \
665  __func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
666  FARM_IMPL_ABORT(); \
667  } \
668  } while (false)
FARM_FORMAT
#define FARM_FORMAT(...)
Formats the cstr using the libfmt library.
Definition: format.h:125
farm_ng
Definition: backtrace.cpp:102
farm_ng::StreamLogger::LogClock::now
std::function< std::string()> now
Definition: logger.h:54
farm_ng::ErrorDetail
Definition: logger.h:401
core.event_service.str
str
Definition: event_service.py:547
farm_ng::FARM_ENUM
FARM_ENUM(LogLevel, int,((trace, 0),(debug, 1),(info, 2),(warning, 3),(error, 4),(critical, 5)))
format.h
farm_ng::details::UnwrapImpl
Definition: logger.h:503
enum.h
sophus::min
auto min(TPoint const &a, TPoint const &b) -> TPoint
Definition: vector_space.h:104
farm_ng::StreamLogger::LogClock
Definition: logger.h:53
core.event_service.args
args
Definition: event_service.py:549
farm_ng::StreamLogger::log
void log(LogLevel log_level, std::string const &header_text, std::string const &file, int line, std::string const &function, std::string const &message, TT &&... args)
Definition: logger.h:61
farm_ng::StreamLogger::setLogClock
void setLogClock(LogClock log_clock)
Definition: logger.cpp:37
farm_ng::StreamLogger::getLogLevel
LogLevel getLogLevel()
Definition: logger.cpp:35
farm_ng::details::CheckNear
Definition: logger.h:311
farm_ng::ErrorDetail::line
int line
Definition: logger.h:403
farm_ng::StreamLogger::log
void log(LogLevel log_level, std::string const &header_text, std::string const &file, int line, std::string const &function)
Definition: logger.h:95
message
cmake message("farm_ng_cmake_DIR" ${farm_ng_cmake_DIR}) include($
Definition: CMakeLists.txt:8
farm_ng::StreamLogger::getHeaderFormat
std::string getHeaderFormat() const
Definition: logger.cpp:30
farm_ng::stringFromLogLevel
auto stringFromLogLevel(LogLevel level) -> std::string
Definition: logger.cpp:21
farm_ng::details::checkedGetFromAssociativeContainer
auto checkedGetFromAssociativeContainer(TContainer &container, TKey const &key, char const *container_cstr, char const *key_cstr, std::string const &file, int line, std::string const &func, std::string const &str) -> decltype(*(container.find(key)))
Definition: logger.h:439
farm_ng::ErrorDetail::file
std::string file
Definition: logger.h:402
core.event_client.level
level
Definition: event_client.py:41
farm_ng::defaultLogger
StreamLogger & defaultLogger()
Definition: logger.h:124
FARM_IMPL_ABORT
#define FARM_IMPL_ABORT()
Definition: format.h:62
farm_ng::StreamLogger
Definition: logger.h:41
farm_ng::details::insertKeyValueInMap
auto insertKeyValueInMap(TMapLike &map, TKey const &key, TValue const &value, char const *container_cstr, char const *key_cstr, char const *value_cstr, std::string const &file, int line, std::string const &func, std::string const &str)
Definition: logger.h:469
farm_ng::StreamLogger::setHeaderFormat
void setHeaderFormat(std::string const &str)
Definition: logger.cpp:27
farm_ng::details::UnwrapImpl::impl
static auto impl(TWrapper &wrapper, char const *wrapper_cstr, ::farm_ng::ErrorDetail detail) -> decltype(*wrapper)
Definition: logger.h:504
farm_ng::StreamLogger::setLogLevel
void setLogLevel(LogLevel level)
Definition: logger.cpp:34
farm_ng::details::CheckNear< TT, std::enable_if_t< std::is_arithmetic_v< TT >, void > >::impl
static void impl(double const &lhs, double const &rhs, double const &thr, char const *lhs_cstr, char const *rhs_cstr, char const *thr_cstr, std::string const &file, int line, std::string const &func, std::string const &str)
Definition: logger.h:315
farm_ng::details::unwrapImpl
auto unwrapImpl(TWrapper &wrapper, char const *wrapper_cstr, ::farm_ng::ErrorDetail detail) -> decltype(*wrapper)
Definition: logger.h:525
farm_ng::ErrorDetail::msg
std::string msg
Definition: logger.h:404
core.event_service_recorder.func
func
Definition: event_service_recorder.py:420
farm_ng::details::checkedAtContiguousContainer
auto checkedAtContiguousContainer(TContainer &container, size_t index, char const *container_cstr, char const *index_cstr, std::string const &file, int line, std::string const &func, std::string const &str) -> decltype(container[index])
Definition: logger.h:410