TerraLib and TerraView Wiki Page

TerraLib.Core: Logger

The class te::core::Logger provides support to create event logs for the application through Boost.Log.

API

C++

The API for create event logs in TerraLib is defined by the Logger class, shown below:

namespace te
{
  namespace core
  {
    class Logger
    {
      /*!
        \class Logger
 
        \brief This class is a singleton designed to manage log messages in TerraLib
       */
      public:
 
        enum severity_level
        {
          trace,
          debug,
          info,
          warning,
          error,
          fatal
        };
 
        /*!
          \brief It returns a reference to the singleton instance.
 
          \return A reference to the singleton instance.
         */
        static Logger& instance();
 
        /*!
          \brief It logs a given string message, channel and severity.
 
          \param message The string message to be logged.
          \param channel The channel name that will receive the message.
          \param severity The severity of the logged message.
        */
        void log(const std::string& message, const std::string &channel, severity_level severity);
 
        /*!
          \brief It sets the logger configuration from a given file.
 
          \param filename The name of the configuration file.
 
          \exception std::exception If the configuration file is doesn't load.
        */
        void addLoggerFromFile(const std::string &filename);
 
        /*!
          \brief It sets the logger using a default implementation.
 
          \param name The name of the logger.
          \param filename The name of the log file.
          \param format The format string of the logger.
 
          \exception te::InvalidArgumentException If the logger name is empty or already registered
 
          \note The logs will be stored in the given file name. If the file already
          exists, the logs will be appended to the end of the file.
        */
        void addLogger(const std::string &name, const std::string &filename, std::string format);
 
        /*!
          \brief Checks if exists a logger registered with the given name.
 
          \param name The name to be checked.
 
          \return True if a logger with the given name, false if not.
         */
        bool exists(const std::string &name);
 
        /*!
          \brief It removes all added loggers.
         */
        void removeAllLoggers();
 
    };
  } //end namespace core
}   //end namespace te

This API uses a channel system to filter log messages, where each channel represents a different logger.

This differentiation is made informing the logger name in macros available to perform the log:

TE_CORE_LOG_TRACE(channel, message)
TE_CORE_LOG_DEBUG(channel, message)
TE_CORE_LOG_INFO(channel, message)
TE_CORE_LOG_WARN(channel, message)
TE_CORE_LOG_ERROR(channel, message)
TE_CORE_LOG_FATAL(channel, message)

Where:

  • channel: logger name.
  • message: message to be logged.

It's possible to define your own logger macros, so that is not necessary to provide the logger name every time a log is made.

#define MEU_LOG_INFO(message) TE_CORE_LOG_INFO("my_log", message)

Configuration File

It is possible to add a logger without providing a configuration file using the macro TE_ADD_LOGGER:

TE_ADD_LOGGER(name, filename, format)

Where:

  • name: logger name.
  • filename: log file name.
  • format: format of the logger messages.

It is also possible to add a logger providing a configuration file using the macro TE_ADD_LOGGER_FROM_FILE:

TE_ADD_LOGGER_FROM_FILE(name, filename)

Where:

  • name: logger name.
  • filename: name of the configuration file.

Here is an example of a configuration file:

[Sinks.MeuLog]
Destination=TextFile
Filter="%Channel% matches \"meu_log\""
FileName="log/meu_log.log"
Format="[%TimeStamp%] <%Severity%> : %Message%"
AutoFlush=true

Note: the messages will be logged in the correct channel if the following filter was added: Filter=“%Channel% matches \”logger_name\“”

The informations to create a configuration file are available in Boost.Log.

Default Logger

It is possible to use a default TerraLib logger with the macro TE_INIT_DEFAULT_LOGGER:

TE_INIT_DEFAULT_LOGGER(filename)

Where:

  • filename: file where messages will be logged.

The default logger of TerraLib consists of 6 macros that can be used to categorize messages in relevant levels:

TE_LOG_TRACE ("Trace log")
/* Used within functions which implement algorithms to check the flow of execution within the function.
   Therefore, this macro should be applied in the inner levels of the algorithm being implemented. */
 
TE_LOG_DEBUG ("Debug log")
/* Used to register messages to inform the values of arguments passed to a function or the return value of this function.
   The purpose of the message is the system debugging. */
 
TE_LOG_INFO("Information log") 
/* Used with messages that indicate the progress of the application or a function. */
 
TE_LOG_WARN("Warning log") 
/* Used to register considered unsafe situations messages to the application. */
 
TE_LOG_ERROR("Error log") 
/* Used to register error messages that do not impede the continued application. */
 
TE_LOG_FATAL("Fatal log") 
/* Used to register event messages that impede the continued application. */

Note: be careful with the fact that the use of macros like TE_LOG_TRACE and TE_LOG_DEBUG together with the message translation mechanism should be avoided to prevent overhead involved in messages translation.

The application and TerraLib must be compiled with the level TE_LOG_TRACE disabled to prevent overcharging with the log record in the archives.

Logger Formatting

The attributes available for use in formatting are:

  • TimeStamp: message date.
  • Severity: message level of relevance.
  • Channel: logger name.
  • Message: message content.
  • Process: process that logged the message.
  • ProcessID: process id.
  • ThreadID: id of the thread that logged the message.

The attributes are used as follow: [%TimeStamp%] %Severity%: %Message%

Examples

Here is a simple example using the functions provided by the Logger class:

// TerraLib
#include <terralib/core/utils/Platform.h>
#include <terralib/core/logger/Logger.h>
 
//Defining my custom logger macro.
#define MY_LOG_WARN(message) TE_CORE_LOG_WARN("mylogger", message)
#define MY_LOG_FATAL(message) TE_CORE_LOG_FATAL("mylogger", message)
#define MY_LOG_DEBUG(message) TE_CORE_LOG_DEBUG("mylogger", message)
 
int main(int argc, char *argv[])
{
 
  //Initializing terralib default logger
  TE_INIT_DEFAULT_LOGGER("logs/terralib.log");
 
  //Adding a logger from a configuration file.
  TE_ADD_LOGGER_FROM_FILE("terralib_example", te::core::FindInTerraLibPath("share/terralib/config/te-log.ini"));
 
  TE_LOG_TRACE("This is a trace log.");
  TE_CORE_LOG_DEBUG("vp", "Logging config file");
  TE_LOG_INFO("This is a info log");
  TE_CORE_LOG_DEBUG("vp", "Logging config file");
  TE_CORE_LOG_DEBUG("mnt", "Logging config file");
  TE_LOG_ERROR("This is a error log");
  TE_CORE_LOG_DEBUG("attributefill", "Logging config file");
 
  //Adding a new logger without configuration file.
  TE_ADD_LOGGER("mylogger", "log/mylogs.log", "[%TimeStamp%]{%ThreadID%} %Process%(%ProcessID%) <%Severity%>: %Message%");
 
  MY_LOG_WARN("This is a warning log.");
  MY_LOG_FATAL("This is a fatal log.");
  TE_LOG_INFO("This is a info log");
  TE_LOG_ERROR("This is a error log");
  MY_LOG_DEBUG("This is a debug log.");
}

Additional References