Logger< L, ASSERTS > Class Template Reference

the Logger class is the main class of the logger implementation. It holds all the functions which invoke certain methods to create messages based on input parameter deductions. More...

#include <Logger.h>

Public Member Functions

 Logger (const std::string name)
 constructor More...
 
 ~Logger ()=default
 destructor More...
 
template<Log LOGLEVEL, typename ... Args>
std::enable_if<!((L< LOGLEVEL) &&(MERCURYDPM_LOGLEVEL< LOGLEVEL)), void >::type operator() (const LL< LOGLEVEL > log, const char *format UNUSED, Args &&... arg UNUSED)
 Log implementation of this function. More...
 
template<Log LOGLEVEL, typename... Args>
std::enable_if< L< LOGLEVEL &&MERCURYDPM_LOGLEVEL< LOGLEVEL, void >::type operator()(const LL< LOGLEVEL > log, const char *format UNUSED, Args &&... arg UNUSED) { } template< Log LOGLEVEL, typename... Args > void operator()(const LL< LOGLEVEL > log, const std::string &format UNUSED, Args &&... arg UNUSED) {(*this)(log, format.c_str(), arg...);} template< typename... Args > typename std::enable_if<(ASSERTS) &&(sizeof...(Args) >=0), void >::type assert_debug(bool assertion, const char *format, Args &&... arg) { assert_always(assertion, format, arg...);} template< typename... Args > typename std::enable_if<!((ASSERTS) &&sizeof...(Args) >=0), void >::type assert_debug(bool assertion, const char *format, Args &&... arg) { } template< typename... Args > void assert_debug(bool assertion, const std::string format, Args &&... arg) { assert_debug(assertion, format.c_str(), arg...);} template< typename... Args > void assert_always(bool assertion, const char *format, Args &&... arg) { if(!assertion) { std::stringstream msgstream;createMessage(msgstream, format, arg...);loggerOutput->onFatal(module, msgstream.str(), doFlush_);} } template< typename... Args > void assert_always(bool assertion, const std::string format, Args &&... arg) { assert_always(assertion, format.c_str(), arg...);} template< typename... Args > MERCURYDPM_DEPRECATED void log(const Log loglevel, const std::string &format, Args &&... arg) { if(loglevel<=L||loglevel<=MERCURYDPM_LOGLEVEL) { std::stringstream msgstream;createMessage(msgstream, format.c_str(), arg...);if(loglevel<=Log::FATAL) { loggerOutput-> onFatal (module, msgstream.str(), doFlush_)
 Empty body function utilized to suppress logger messages above a certain user defined loglevel L. More...
 
else if (loglevel<=Log::ERROR)
 
else if (loglevel<=Log::WARN)
 
else if (loglevel<=Log::INFO)
 
else if (loglevel<=Log::VERBOSE)
 

Public Attributes

 else
 
 doFlush_ = Flusher::FLUSH
 

Private Member Functions

template<typename Arg1 , typename... Args>
void createMessage (std::stringstream &msg, const char *fmt, Arg1 &&arg, Args &&... args)
 Edits the message to a certain format and writes it to a stringstream by recursively replacing all % characters with the arguments values. More...
 
template<typename... Args>
void createMessage (std::stringstream &msg, const char *fmt, Flusher arg, Args &&... args)
 Overloaded version of createMessage to catch arguments of Flusher and suppress input flushing via std::endl. If there is an argument which should be catched from the logger, overloading the function is the way to go. More...
 
template<typename Arg1 >
void createMessage (std::stringstream &msg, const char *fmt, Arg1 &&arg)
 Terminating case / Argument call. Overloaded function for a logger message with only one argument or where only one argument is left. More...
 
void createMessage (std::stringstream &msg, const char *message)
 Terminating case / no argument call Overloaded function for a logger message without arguments. More...
 

Private Attributes

const std::string module
 The module name of this actual logger. More...
 
Flusher doFlush_ = Flusher::FLUSH
 Can prevent the logger from flushing the buffer via std::endl. doFlush_ is set automatically based on build and loglevel settings. More...
 

Detailed Description

template<Log L, bool ASSERTS>
class Logger< L, ASSERTS >

the Logger class is the main class of the logger implementation. It holds all the functions which invoke certain methods to create messages based on input parameter deductions.

Template Parameters
LThe log level defined in cMake configuration. Messages of higher level than L are ignored.

Usage: logger(FATAL, "Error in (here) because % < %!\n", var1, var2) OUTPUT: Error in (here) because 2 < 1!

Define custom loggers by: ifndef HG_LOGLEVEL_CUSTOMMOD define HG_LOGLEVEL_CUSTOMMOD Log::Debug endif Logger<HG_LOGLEVEL_CUSTOMMOD> customLogger;

Constructor & Destructor Documentation

◆ Logger()

template<Log L, bool ASSERTS>
Logger< L, ASSERTS >::Logger ( const std::string  name)
inlineexplicit

constructor

Parameters
[in]nameThe name in this module used in output messages.
326  : module(name)
327  {
328  }
const std::string module
The module name of this actual logger.
Definition: Logger.h:311
std::string name
Definition: MercuryProb.h:48

◆ ~Logger()

template<Log L, bool ASSERTS>
Logger< L, ASSERTS >::~Logger ( )
default

destructor

Member Function Documentation

◆ createMessage() [1/4]

template<Log L, bool ASSERTS>
template<typename Arg1 >
void Logger< L, ASSERTS >::createMessage ( std::stringstream &  msg,
const char fmt,
Arg1 &&  arg 
)
inlineprivate

Terminating case / Argument call. Overloaded function for a logger message with only one argument or where only one argument is left.

Parameters
[in]msgstringstream which represents the output message.
[in]fmtchar array of the yet unformatted message.
[in]argargument to replace the next % character.
653  {
654  bool doSkipNext = false;
655  while (*fmt != '%' || doSkipNext)
656  {
657  if (*fmt == '\0') // End of string
658  return;
659 
660  if (*fmt == '\\' && !doSkipNext)
661  { //Escape for the % character and the \ character
662  doSkipNext = true;
663  fmt++;
664  }
665  else
666  { //invoke the replacement
667  msg << *fmt;
668  fmt++;
669  doSkipNext = false;
670  }
671  }
672  fmt++; //Consume the % character
673  int precision = 0;
674  int width = 0;
675  // if precision and width or only precision is defined
676  if (isdigit(*fmt))
677  {
678  precision = std::atoi(fmt);
679  while (isdigit(*fmt))
680  {
681  fmt++;
682  }
683  if (std::ispunct(*fmt))
684  {
685  fmt++;
686  if (std::isdigit(*fmt))
687  {
688  width = std::atoi(fmt);
689  while (isdigit(*fmt))
690  {
691  fmt++;
692  }
693  }
694  // else the char is a real full stop so set the pointer back to full stop.
695  else
696  {
697  fmt--;
698  }
699  }
700  }
701  // if only a width and no precision defined
702  else if (std::ispunct(*fmt))
703  {
704  fmt++;
705  if (std::isdigit(*fmt))
706  {
707  width = std::atoi(fmt);
708  while (isdigit(*fmt))
709  {
710  fmt++;
711  }
712  }
713  // else the char is a real full stop so set the pointer back to full stop.
714  else
715  {
716  fmt--;
717  }
718  }
719  if (width != 0 && precision != 0)
720  {
721  msg << std::setprecision(precision) << std::left << std::setw(width) << arg << fmt;
722  }
723  else if (precision != 0)
724  {
725  msg << std::setprecision(precision) << arg << fmt;
726  }
727  else if (width != 0)
728  {
729  msg << std::left << std::setw(width) << arg << fmt;
730  }
731  else
732  {
733  msg << arg << fmt;
734  }
735  }

◆ createMessage() [2/4]

template<Log L, bool ASSERTS>
template<typename Arg1 , typename... Args>
void Logger< L, ASSERTS >::createMessage ( std::stringstream &  msg,
const char fmt,
Arg1 &&  arg,
Args &&...  args 
)
inlineprivate

Edits the message to a certain format and writes it to a stringstream by recursively replacing all % characters with the arguments values.

The creation of messages is divided into three different overloaded functions. the function createMessage is recursively called and each of the functions below is called for a certain case dependent on the amount and type of parameters.

Parameters
[in]msgstringstream which represents the output message.
[in]fmtchar array of the yet unformatted message.
[in]argargument to replace the next % character.
[in]argsparameter pack of the remaining arguments.
526  {
527  bool doSkipNext = false;
528  while (*fmt != '%' || doSkipNext)
529  {
530  //Make sure we're not running past the end of our formatting string.
531  if (*fmt == '\0')
532  return;
533 
534  if (*fmt == '\\' && !doSkipNext)
535  { //Escape for the % character
536  doSkipNext = true;
537  fmt++;
538  }
539  else
540  {
541  msg << *fmt;
542  fmt++;
543  doSkipNext = false;
544  }
545  }
546  fmt++; //Consume the % character
547  int precision = 0;
548  int width = 0;
549  // if precision and width or only precision is defined
550  if (isdigit(*fmt))
551  {
552  precision = std::atoi(fmt);
553  while (isdigit(*fmt))
554  {
555  fmt++;
556  }
557  if (std::ispunct(*fmt))
558  {
559  fmt++;
560  if (std::isdigit(*fmt))
561  {
562  width = std::atoi(fmt);
563  while (isdigit(*fmt))
564  {
565  fmt++;
566  }
567  }
568  // else the char is a real full stop so set the pointer back to full stop.
569  else
570  {
571  fmt--;
572  }
573  }
574  }
575  // if only a width and no precision defined
576  else if (std::ispunct(*fmt))
577  {
578  fmt++;
579  if (std::isdigit(*fmt))
580  {
581  width = std::atoi(fmt);
582  while (isdigit(*fmt))
583  {
584  fmt++;
585  }
586  }
587  // else the char is a real full stop so set the pointer back to full stop.
588  else
589  {
590  fmt--;
591  }
592  }
593  if (width != 0 && precision != 0)
594  {
595  msg << std::setprecision(precision) << std::left << std::setw(width) << arg;
596  }
597  else if (precision != 0)
598  {
599  msg << std::setprecision(precision) << arg;
600  }
601  else if (width != 0)
602  {
603  msg << std::left << std::setw(width) << arg;
604  }
605  else
606  {
607  msg << arg;
608  } //include args somehow..
609  createMessage(msg, fmt, args...);//and recursively call ourselve / the method below.
610  }
void createMessage(std::stringstream &msg, const char *fmt, Arg1 &&arg, Args &&... args)
Edits the message to a certain format and writes it to a stringstream by recursively replacing all % ...
Definition: Logger.h:524

Referenced by Logger< L, ASSERTS >::createMessage(), and Logger< L, ASSERTS >::operator()().

◆ createMessage() [3/4]

template<Log L, bool ASSERTS>
template<typename... Args>
void Logger< L, ASSERTS >::createMessage ( std::stringstream &  msg,
const char fmt,
Flusher  arg,
Args &&...  args 
)
inlineprivate

Overloaded version of createMessage to catch arguments of Flusher and suppress input flushing via std::endl. If there is an argument which should be catched from the logger, overloading the function is the way to go.

Parameters
[in]msgstringstream which represents the output message.
[in]fmtchar array of the yet unformatted message.
[in]argargument of type Flusher which will be skipped and does not replace the next % character.
[in]argsparameter pack of the remaining parameters.
628  {
629  // only suppress flushing if Mercury is not in CMAKE_BUILD_TYPE "Debug" and if the user defined loglevel from
630  // cMake is below VERBOSE/DEBUG (<=5)
631 #ifndef MERCURYDPM_DEBUG
633  {
635  }
636 #endif
637  // skip this argument by recursively calling this function again
638  createMessage(msg, fmt, args...);
639  }
@ VERBOSE
#define MERCURYDPM_LOGLEVEL
Definition: Logger.h:38
Flusher doFlush_
Can prevent the logger from flushing the buffer via std::endl. doFlush_ is set automatically based on...
Definition: Logger.h:316

References Logger< L, ASSERTS >::createMessage(), Logger< L, ASSERTS >::doFlush_, FLUSH, MERCURYDPM_LOGLEVEL, NO_FLUSH, and VERBOSE.

◆ createMessage() [4/4]

template<Log L, bool ASSERTS>
void Logger< L, ASSERTS >::createMessage ( std::stringstream &  msg,
const char message 
)
inlineprivate

Terminating case / no argument call Overloaded function for a logger message without arguments.

Parameters
[in]msgstringstream which represents the output message.
[in]messagechar array of the message.
746  {
747  msg << message;
748  }

◆ if() [1/4]

template<Log L, bool ASSERTS>
else Logger< L, ASSERTS >::if ( loglevel<=Log::ERROR  )
inline
481  {
482  loggerOutput->onError(module, msgstream.str(), doFlush_);
483  }
LoggerOutput * loggerOutput
Declaration of the output functions.
Definition: Logger.cc:283
std::function< void(std::string, std::string, Flusher)> onError
Definition: Logger.h:160

References Logger< L, ASSERTS >::doFlush_, loggerOutput, Logger< L, ASSERTS >::module, and LoggerOutput::onError.

◆ if() [2/4]

template<Log L, bool ASSERTS>
else Logger< L, ASSERTS >::if ( loglevel<=Log::INFO  )
inline
490  {
491  loggerOutput->onInfo(module, msgstream.str(), doFlush_);
493  }
std::function< void(std::string, std::string, Flusher)> onInfo
Definition: Logger.h:162

References Logger< L, ASSERTS >::doFlush_, FLUSH, loggerOutput, Logger< L, ASSERTS >::module, and LoggerOutput::onInfo.

◆ if() [3/4]

template<Log L, bool ASSERTS>
else Logger< L, ASSERTS >::if ( loglevel<=Log::VERBOSE  )
inline
495  {
496  loggerOutput->onVerbose(module, msgstream.str(), doFlush_);
498  }
std::function< void(std::string, std::string, Flusher)> onVerbose
Definition: Logger.h:163

References Logger< L, ASSERTS >::doFlush_, FLUSH, loggerOutput, Logger< L, ASSERTS >::module, and LoggerOutput::onVerbose.

◆ if() [4/4]

template<Log L, bool ASSERTS>
else Logger< L, ASSERTS >::if ( loglevel<=Log::WARN  )
inline
485  {
486  loggerOutput->onWarn(module, msgstream.str(), doFlush_);
488  }
std::function< void(std::string, std::string, Flusher)> onWarn
Definition: Logger.h:161

References Logger< L, ASSERTS >::doFlush_, FLUSH, loggerOutput, Logger< L, ASSERTS >::module, and LoggerOutput::onWarn.

◆ onFatal()

template<Log L, bool ASSERTS>
template<Log LOGLEVEL, typename... Args>
std::enable_if<L < LOGLEVEL && MERCURYDPM_LOGLEVEL < LOGLEVEL, void>::type operator()(const LL<LOGLEVEL> log, const char* format UNUSED, Args&& ... arg UNUSED) { } template<Log LOGLEVEL, typename... Args> void operator()(const LL<LOGLEVEL> log, const std::string& format UNUSED, Args&& ... arg UNUSED) { (*this)(log, format.c_str(), arg...); } template<typename... Args> typename std::enable_if<(ASSERTS) && (sizeof...(Args) >= 0), void>::type assert_debug(bool assertion, const char* format, Args&& ... arg) { assert_always(assertion, format, arg...); } template<typename... Args> typename std::enable_if<!((ASSERTS) && sizeof...(Args) >= 0), void>::type assert_debug(bool assertion, const char* format, Args&& ... arg) { } template<typename... Args> void assert_debug(bool assertion, const std::string format, Args&& ... arg) { assert_debug(assertion, format.c_str(), arg...); } template<typename... Args> void assert_always(bool assertion, const char* format, Args&& ... arg) { if (!assertion) { std::stringstream msgstream; createMessage(msgstream, format, arg...); loggerOutput->onFatal(module, msgstream.str(), doFlush_); } } template<typename... Args> void assert_always(bool assertion, const std::string format, Args&& ... arg) { assert_always(assertion, format.c_str(), arg...); } template<typename... Args> MERCURYDPM_DEPRECATED void log(const Log loglevel, const std::string& format, Args&& ... arg) { if (loglevel <= L || loglevel <= MERCURYDPM_LOGLEVEL) { std::stringstream msgstream; createMessage(msgstream, format.c_str(), arg...); if (loglevel <= Log::FATAL) { loggerOutput-> Logger< L, ASSERTS >::onFatal ( module  ,
msgstream.  str(),
doFlush_   
)

Empty body function utilized to suppress logger messages above a certain user defined loglevel L.

◆ operator()()

template<Log L, bool ASSERTS>
template<Log LOGLEVEL, typename ... Args>
std::enable_if<!((L < LOGLEVEL) && (MERCURYDPM_LOGLEVEL < LOGLEVEL)), void>::type Logger< L, ASSERTS >::operator() ( const LL< LOGLEVEL >  log,
const char *format  UNUSED,
Args &&... arg  UNUSED 
)
inline

Log implementation of this function.

Actual implementation of the log function. If the user defined loglevel L is lower than the called LOGLEVEL it will evaluate to an empty body function below. If L is greater than the called LOGLEVEL it will invoke this function.

Parameters
[in]logLoglevel, either FATAL, ERROR, WARN, INFO, VERBOSE, DEBUG
[in]formatMessage format, where % can be used as a placeholder for arguments.
[in]argAny arguments which replace all the % characters.
352  {
353  std::stringstream msgstream;
354  createMessage(msgstream, format, arg...);
355  if (LOGLEVEL <= Log::FATAL)
356  {
357  loggerOutput->onFatal(module, msgstream.str(), doFlush_);
358  }
359  else if (LOGLEVEL <= Log::ERROR)
360  {
361  loggerOutput->onError(module, msgstream.str(), doFlush_);
362  }
363  else if (LOGLEVEL <= Log::WARN)
364  {
365  loggerOutput->onWarn(module, msgstream.str(), doFlush_);
367  }
368  else if (LOGLEVEL <= Log::INFO)
369  {
370  loggerOutput->onInfo(module, msgstream.str(), doFlush_);
372  }
373  else if (LOGLEVEL <= Log::VERBOSE)
374  {
375  loggerOutput->onVerbose(module, msgstream.str(), doFlush_);
377  }
378  else
379  {
380  loggerOutput->onDebug(module, msgstream.str(), doFlush_ = Flusher::FLUSH);
382  }
383  }
@ FATAL
@ WARN
@ INFO
@ ERROR
std::function< void(std::string, std::string, Flusher)> onFatal
Definition: Logger.h:159
std::function< void(std::string, std::string, Flusher)> onDebug
Definition: Logger.h:164

References Logger< L, ASSERTS >::createMessage(), Logger< L, ASSERTS >::doFlush_, ERROR, FATAL, FLUSH, INFO, loggerOutput, Logger< L, ASSERTS >::module, LoggerOutput::onDebug, LoggerOutput::onError, LoggerOutput::onFatal, LoggerOutput::onInfo, LoggerOutput::onVerbose, LoggerOutput::onWarn, VERBOSE, and WARN.

Member Data Documentation

◆ doFlush_ [1/2]

template<Log L, bool ASSERTS>
Flusher Logger< L, ASSERTS >::doFlush_ = Flusher::FLUSH
private

Can prevent the logger from flushing the buffer via std::endl. doFlush_ is set automatically based on build and loglevel settings.

Referenced by Logger< L, ASSERTS >::createMessage(), Logger< L, ASSERTS >::if(), and Logger< L, ASSERTS >::operator()().

◆ doFlush_ [2/2]

template<Log L, bool ASSERTS>
Logger< L, ASSERTS >::doFlush_ = Flusher::FLUSH

◆ else

template<Log L, bool ASSERTS>
Logger< L, ASSERTS >::else
Initial value:
{
LoggerOutput * loggerOutput
Declaration of the output functions.
Definition: Logger.cc:283

◆ module

template<Log L, bool ASSERTS>
const std::string Logger< L, ASSERTS >::module
private

The module name of this actual logger.

Referenced by Logger< L, ASSERTS >::if(), and Logger< L, ASSERTS >::operator()().


The documentation for this class was generated from the following file: