farm-ng-core
logger.h File Reference
#include "farm_ng/core/enum/enum.h"
#include "farm_ng/core/logging/format.h"
#include <farm_pp/preprocessor/comma.hpp>
#include <farm_pp/preprocessor/empty.hpp>
#include <atomic>
#include <filesystem>
#include <unordered_set>
Include dependency graph for logger.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  farm_ng::StreamLogger
 
struct  farm_ng::StreamLogger::LogClock
 
struct  farm_ng::details::CheckNear< TPoint, TEnabler >
 
struct  farm_ng::details::CheckNear< TT, std::enable_if_t< std::is_arithmetic_v< TT >, void > >
 
struct  farm_ng::ErrorDetail
 
struct  farm_ng::details::UnwrapImpl< TWrapper >
 

Namespaces

 farm_ng
 
 farm_ng::details
 

Macros

#define FARM_VARGS(...)   FARM_PP_COMMA() __VA_ARGS__
 
#define FARM_VARGS_NONE(...)
 
#define FARM_MAYBE_VARGS(...)
 
#define FARM_LOG_ENABLED   1
 
#define FARM_INFO(...)
 Log level to be used for more noisy FYI type of status. Don't use FARM_INFO if the pure compile-time invocation of the macro would hurt performance. E.g. if this code might be executed within an inner loop such as for every pixel of an image. Use FARM_DEBUG or FARM_TRACE instead which can be toggled at compile-time (and are turned off by default). More...
 
#define FARM_WARN(...)
 More significant information with high signal to noise. Typically to communicate an usual but valid state of the program. More...
 
#define FARM_ERROR(...)
 Error state (but not logical error/precondition violation nor panic). Currently not used. More...
 
#define FARM_CRITICAL(...)
 Critical error state to communicated. Often followed by a panic (i.e. std::abort, if enabled). More...
 
#define FARM_IMPL_ASSERT_OP(symbol, name_str, lhs, rhs, ...)
 
#define FARM_IMPL_LOG_HEADER(msg)   FARM_IMPL_LOG_PRINTLN("[FARM {} in {}:{}]", msg, __FILE__, __LINE__)
 
#define FARM_PANIC(...)
 Print formatted error message and then panic. More...
 
#define FARM_UNIMPLEMENTED(...)
 Print formatted error message and then panic. More...
 
#define FARM_PRINTLN(cstr, ...)   FARM_IMPL_LOG_PRINTLN(cstr, ##__VA_ARGS__)
 
#define FARM_INFO_EVERY_N(N, ...)
 LOG INFO: Only log every nth encounter. More...
 
#define FARM_ASSERT(condition, ...)
 If condition is false, Print formatted error message and then panic. More...
 
#define FARM_ASSERT_EQ(lhs, rhs, ...)   FARM_IMPL_ASSERT_OP(==, "EQ", lhs, rhs, __VA_ARGS__)
 If it is false that lhs == rhs, print formatted error message and then panic. More...
 
#define FARM_ASSERT_NE(lhs, rhs, ...)   FARM_IMPL_ASSERT_OP(!=, "NE", lhs, rhs, __VA_ARGS__)
 If it is false that lhs != rhs, print formatted error message and then panic. More...
 
#define FARM_ASSERT_LE(lhs, rhs, ...)   FARM_IMPL_ASSERT_OP(<=, "LE", lhs, rhs, __VA_ARGS__)
 If it is false that lhs <= rhs, print formatted error message and then panic. More...
 
#define FARM_ASSERT_LT(lhs, rhs, ...)   FARM_IMPL_ASSERT_OP(<, "LT", lhs, rhs, __VA_ARGS__)
 If it is false that lhs < rhs, print formatted error message and then panic. More...
 
#define FARM_ASSERT_GE(lhs, rhs, ...)   FARM_IMPL_ASSERT_OP(>=, "GE", lhs, rhs, __VA_ARGS__)
 If it is false that lhs >= rhs, print formatted error message and then panic. More...
 
#define FARM_ASSERT_GT(lhs, rhs, ...)   FARM_IMPL_ASSERT_OP(>, "GT", lhs, rhs, __VA_ARGS__)
 If it is false that lhs > rhs, print formatted error message and then panic. More...
 
#define FARM_ASSERT_NEAR(lhs, rhs, thr, ...)
 If it is false that lhs is near rhs according to threshold thr, print formatted error message and then panic. More...
 
#define FARM_AT(contiguous_container, index, ...)
 Returns contiguous_container[index], but panics if index is out of bounds. More...
 
#define FARM_GET(associative_container, key, ...)
 Returns associative_container[key], but panics if the container does not contain key . More...
 
#define FARM_MAP_INSERT(map, key, value, ...)
 Insert val to map, but panics if the container does contain key already. More...
 
#define FARM_UNWRAP(wrapper, ...)
 Returns *wrapper, but panics if wrapper is nullopt or null. More...
 
#define FARM_ASSERT_PATH_EXIST(path, ...)
 Asserts that the given path exits. More...
 
#define FARM_ASSERT_IS_FILE(path, ...)
 Asserts that the given path is a regular file. Hence it asserts that a) it does exit, b) it is a regular file. More...
 
#define FARM_ASSERT_IS_FOLDER(path, ...)
 Asserts that the given path is a folder. Hence it asserts that a) it does exit, b) it is a folder (and not a file). More...
 
#define FARM_ASSERT_FOLDER_IS_EMPTY(path, ...)
 Asserts that the given path is an empty folder. Hence it asserts that a) it does exit, b) it is a folder (and not a file), c) it is empty. More...
 

Functions

 farm_ng::FARM_ENUM (LogLevel, int,((trace, 0),(debug, 1),(info, 2),(warning, 3),(error, 4),(critical, 5)))
 
auto farm_ng::stringFromLogLevel (LogLevel level) -> std::string
 
StreamLogger & farm_ng::defaultLogger ()
 
template<class TContainer >
auto farm_ng::details::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])
 
template<class TContainer , class TKey >
auto farm_ng::details::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)))
 
template<class TMapLike , class TKey , class TValue >
auto farm_ng::details::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)
 
template<class TWrapper >
auto farm_ng::details::unwrapImpl (TWrapper &wrapper, char const *wrapper_cstr, ::farm_ng::ErrorDetail detail) -> decltype(*wrapper)
 

Macro Definition Documentation

◆ FARM_ASSERT

#define FARM_ASSERT (   condition,
  ... 
)
Value:
do { \
if (!(condition)) { \
farm_ng::LogLevel::critical, \
FARM_FORMAT("PANIC: ASSERT failed\nbool({}) not true.", #condition), \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT(); \
} \
} while (false)

If condition is false, Print formatted error message and then panic.

◆ FARM_ASSERT_EQ

#define FARM_ASSERT_EQ (   lhs,
  rhs,
  ... 
)    FARM_IMPL_ASSERT_OP(==, "EQ", lhs, rhs, __VA_ARGS__)

If it is false that lhs == rhs, print formatted error message and then panic.

◆ FARM_ASSERT_FOLDER_IS_EMPTY

#define FARM_ASSERT_FOLDER_IS_EMPTY (   path,
  ... 
)
Value:
do { \
FARM_ASSERT_IS_FOLDER(path); \
bool is_empty = std::filesystem::is_empty(path); \
if (!is_empty) { \
farm_ng::LogLevel::critical, \
"PANIC: ASSERT_FOLDER_IS_EMPTY failed\nThe following folder is " \
"not empty: {}", \
path), \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT(); \
} \
} while (false)

Asserts that the given path is an empty folder. Hence it asserts that a) it does exit, b) it is a folder (and not a file), c) it is empty.

◆ FARM_ASSERT_GE

#define FARM_ASSERT_GE (   lhs,
  rhs,
  ... 
)    FARM_IMPL_ASSERT_OP(>=, "GE", lhs, rhs, __VA_ARGS__)

If it is false that lhs >= rhs, print formatted error message and then panic.

◆ FARM_ASSERT_GT

#define FARM_ASSERT_GT (   lhs,
  rhs,
  ... 
)    FARM_IMPL_ASSERT_OP(>, "GT", lhs, rhs, __VA_ARGS__)

If it is false that lhs > rhs, print formatted error message and then panic.

◆ FARM_ASSERT_IS_FILE

#define FARM_ASSERT_IS_FILE (   path,
  ... 
)
Value:
do { \
FARM_ASSERT_PATH_EXIST(path); \
bool is_regular = std::filesystem::is_regular_file(path); \
if (!is_regular) { \
farm_ng::LogLevel::critical, \
"PANIC: ASSERT_IS_FILE failed\nThe following path is not a " \
"regular file: {}", \
path), \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT(); \
} \
} while (false)

Asserts that the given path is a regular file. Hence it asserts that a) it does exit, b) it is a regular file.

◆ FARM_ASSERT_IS_FOLDER

#define FARM_ASSERT_IS_FOLDER (   path,
  ... 
)
Value:
do { \
FARM_ASSERT_PATH_EXIST(path); \
bool is_folder = std::filesystem::is_directory(path); \
if (!is_folder) { \
farm_ng::LogLevel::critical, \
"PANIC: ASSERT_IS_FOLDER failed\nThe following path is not a " \
"folder: {}", \
path), \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT(); \
} \
} while (false)

Asserts that the given path is a folder. Hence it asserts that a) it does exit, b) it is a folder (and not a file).

◆ FARM_ASSERT_LE

#define FARM_ASSERT_LE (   lhs,
  rhs,
  ... 
)    FARM_IMPL_ASSERT_OP(<=, "LE", lhs, rhs, __VA_ARGS__)

If it is false that lhs <= rhs, print formatted error message and then panic.

◆ FARM_ASSERT_LT

#define FARM_ASSERT_LT (   lhs,
  rhs,
  ... 
)    FARM_IMPL_ASSERT_OP(<, "LT", lhs, rhs, __VA_ARGS__)

If it is false that lhs < rhs, print formatted error message and then panic.

◆ FARM_ASSERT_NE

#define FARM_ASSERT_NE (   lhs,
  rhs,
  ... 
)    FARM_IMPL_ASSERT_OP(!=, "NE", lhs, rhs, __VA_ARGS__)

If it is false that lhs != rhs, print formatted error message and then panic.

◆ FARM_ASSERT_NEAR

#define FARM_ASSERT_NEAR (   lhs,
  rhs,
  thr,
  ... 
)
Value:
::farm_ng::details::CheckNear<std::decay_t<decltype(lhs)>>::impl( \
lhs, \
rhs, \
thr, \
#lhs, \
#rhs, \
#thr, \
__FILE__, \
__LINE__, \
__func__, \
FARM_FORMAT(__VA_ARGS__))

If it is false that lhs is near rhs according to threshold thr, print formatted error message and then panic.

lhs and rhs are near, if maxMetric(lhs, rhs) < thr.

◆ FARM_ASSERT_PATH_EXIST

#define FARM_ASSERT_PATH_EXIST (   path,
  ... 
)
Value:
do { \
bool does_exist = std::filesystem::exists(path); \
if (!does_exist) { \
farm_ng::LogLevel::critical, \
"PANIC: ASSERT_PATH_EXIST failed\nThe following path does not " \
"exist: {}", \
path), \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT(); \
} \
} while (false)

Asserts that the given path exits.

◆ FARM_AT

#define FARM_AT (   contiguous_container,
  index,
  ... 
)
Value:
contiguous_container, \
index, \
#contiguous_container, \
#index, \
__FILE__, \
__LINE__, \
__func__, \
FARM_FORMAT(__VA_ARGS__))

Returns contiguous_container[index], but panics if index is out of bounds.

◆ FARM_CRITICAL

#define FARM_CRITICAL (   ...)
Value:
farm_ng::LogLevel::critical, \
"CRITICAL", \
__FILE__, \
__LINE__, \
__func__, \
__VA_ARGS__)

Critical error state to communicated. Often followed by a panic (i.e. std::abort, if enabled).

◆ FARM_ERROR

#define FARM_ERROR (   ...)
Value:
farm_ng::LogLevel::error, \
"ERROR", \
__FILE__, \
__LINE__, \
__func__, \
__VA_ARGS__)

Error state (but not logical error/precondition violation nor panic). Currently not used.

◆ FARM_GET

#define FARM_GET (   associative_container,
  key,
  ... 
)
Value:
associative_container, \
key, \
#associative_container, \
#key, \
__FILE__, \
__LINE__, \
__func__, \
FARM_FORMAT(__VA_ARGS__))

Returns associative_container[key], but panics if the container does not contain key .

◆ FARM_IMPL_ASSERT_OP

#define FARM_IMPL_ASSERT_OP (   symbol,
  name_str,
  lhs,
  rhs,
  ... 
)
Value:
do { \
if (!((lhs)symbol(rhs))) { \
farm_ng::LogLevel::critical, \
"PANIC: ASSERT_{} failed\n Not true: {} {} {}\n{}\nvs.\n{}\n", \
name_str, \
#lhs, \
#symbol, \
#rhs, \
lhs, \
rhs), \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT(); \
} \
} while (false)

◆ FARM_IMPL_LOG_HEADER

#define FARM_IMPL_LOG_HEADER (   msg)    FARM_IMPL_LOG_PRINTLN("[FARM {} in {}:{}]", msg, __FILE__, __LINE__)

◆ FARM_INFO

#define FARM_INFO (   ...)
Value:
farm_ng::LogLevel::info, \
"INFO", \
__FILE__, \
__LINE__, \
__func__, \
__VA_ARGS__)

Log level to be used for more noisy FYI type of status. Don't use FARM_INFO if the pure compile-time invocation of the macro would hurt performance. E.g. if this code might be executed within an inner loop such as for every pixel of an image. Use FARM_DEBUG or FARM_TRACE instead which can be toggled at compile-time (and are turned off by default).

◆ FARM_INFO_EVERY_N

#define FARM_INFO_EVERY_N (   N,
  ... 
)
Value:
do { \
static std::atomic<int> counter(0); \
++counter; \
if (counter > (N)) { \
counter -= (N); \
} \
if (counter == 1) { \
farm_ng::LogLevel::info, \
FARM_FORMAT("LOG INFO EVERY N( = {} )", #N), \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
} \
} while (false)

LOG INFO: Only log every nth encounter.

◆ FARM_LOG_ENABLED

#define FARM_LOG_ENABLED   1

◆ FARM_MAP_INSERT

#define FARM_MAP_INSERT (   map,
  key,
  value,
  ... 
)
Value:
map, \
key, \
value, \
#map, \
#key, \
#value, \
__FILE__, \
__LINE__, \
__func__, \
FARM_FORMAT(__VA_ARGS__))

Insert val to map, but panics if the container does contain key already.

◆ FARM_MAYBE_VARGS

#define FARM_MAYBE_VARGS (   ...)
Value:
FARM_PP_IF( \
FARM_PP_EQUAL(FARM_PP_VARIADIC_SIZE(dummy, ##__VA_ARGS__), 1), \

◆ FARM_PANIC

#define FARM_PANIC (   ...)
Value:
farm_ng::LogLevel::critical, \
"PANIC!", \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT()

Print formatted error message and then panic.

◆ FARM_PRINTLN

#define FARM_PRINTLN (   cstr,
  ... 
)    FARM_IMPL_LOG_PRINTLN(cstr, ##__VA_ARGS__)

◆ FARM_UNIMPLEMENTED

#define FARM_UNIMPLEMENTED (   ...)
Value:
farm_ng::LogLevel::critical, \
"PANIC: NOT IMPLEMENTED YET", \
__FILE__, \
__LINE__, \
__func__ FARM_MAYBE_VARGS(__VA_ARGS__)(__VA_ARGS__)); \
FARM_IMPL_ABORT()

Print formatted error message and then panic.

◆ FARM_UNWRAP

#define FARM_UNWRAP (   wrapper,
  ... 
)
Value:
wrapper, \
#wrapper, \
.file = __FILE__, \
.line = __LINE__, \
.msg = FARM_FORMAT(__VA_ARGS__)})

Returns *wrapper, but panics if wrapper is nullopt or null.

◆ FARM_VARGS

#define FARM_VARGS (   ...)    FARM_PP_COMMA() __VA_ARGS__

◆ FARM_VARGS_NONE

#define FARM_VARGS_NONE (   ...)

◆ FARM_WARN

#define FARM_WARN (   ...)
Value:
farm_ng::LogLevel::warning, \
"WARN", \
__FILE__, \
__LINE__, \
__func__, \
__VA_ARGS__)

More significant information with high signal to noise. Typically to communicate an usual but valid state of the program.

FARM_FORMAT
#define FARM_FORMAT(...)
Formats the cstr using the libfmt library.
Definition: format.h:125
FARM_VARGS
#define FARM_VARGS(...)
Definition: logger.h:132
farm_ng::ErrorDetail
Definition: logger.h:401
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_VARGS_NONE
#define FARM_VARGS_NONE(...)
Definition: logger.h:134
farm_ng::details::CheckNear
Definition: logger.h:311
FARM_MAYBE_VARGS
#define FARM_MAYBE_VARGS(...)
Definition: logger.h:136
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
farm_ng::defaultLogger
StreamLogger & defaultLogger()
Definition: logger.h:124
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::details::unwrapImpl
auto unwrapImpl(TWrapper &wrapper, char const *wrapper_cstr, ::farm_ng::ErrorDetail detail) -> decltype(*wrapper)
Definition: logger.h:525
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