C++ Trivial Logger Tutorial

Introduction

The library is designed to be included into the projects contents without external compilation. This kind of design was chosen because library contains two header files and one code file. And also library interacts with compilation flags, so there is a need to make desired compilation with library included as a part of the program.
Present release contains files:
  • tri_logger.hpp
  • tri_logger.cpp
  • nullstream.hpp

Usage

The most important part of usage the library is to decide which available stream has to be chosen at the beginning of the program - when the program launch. Once more there is very important to highlight that usual programs starting before main() function. So the CxxTL have to be initialized before it will be used.
The flexibility of the logger lies because it uses overloaded operator<<. Therefore all user stream operations will be reused in logger. However simplicity of the library allow in few minutes to define own kind of logging functionality (see User-defined extensions).
Configuration of the code belongs to the user. Important files are: Next do the following steps:
  • Copy those files somewhere to the project directory.
  • Next is to add tri_logger.cpp file to the project make file.
  • Concentrate on the compile time configuration of the Trivial Logger.
C++ Trivial Logger uses three definitions that have to be passed as compilation flags to the compiled code.
  • The first flag is TLOG. This flag set that logger will send information to the standard output (std::cout).
  • The second flag is ETLOG. This flag set that logger will send information to the standard error output (std::cerr).
  • The third flag is FTLOG. This flag set that logger will send information to the output file stream (std::ofstream). By default CxxTL uses _logger.log file. If this option will be passed with additional parameter, then this parameter will be treated as desired filename. As example we can write: FTLOG=my_logger_file_name.log User can pass file names with spaces e.g. FTLOG="my logger file name.log" There are two things the first one is to remember put quotation sign, the second one is that present version of the library will transform all spaces into underscore signs.
Below are shown all function like macros which are defined in library in simple source code.
Demonstration program can be downloaded from SourceForge web site.
#include "tri_logger.hpp"

void finalize()
{
  TRI_LOG_STR("atexit()->finalize()->EXIT_SUCCESS");
}

template < typename T, typename U >
std::ostream & operator<< ( std::ostream & os, std::pair < T, U > const & p )
{
  os << "( " << p.first << ", " << p.second << " )";
  return os;
}

int main ()
{
  std::atexit(finalize);
  double const a = 1.0;
  std::string const str = "test";
  std::pair < std::string, double > p ( "PI", 3.1415 );
  std::pair < unsigned long, std::string > q ( 10, "EUR" );

  TRI_LOG_STR ("Trivial logger in main().");
  TRI_LOG (a);
  TRI_LOG (str);
  TRI_LOG (p);

  TRI_LOG_OFF();
  TRI_LOG_STR ("Trivial logger in main().");

  TRI_LOG_ON();
  TRI_LOG_STR("Test of the user-defined TRI_LOG_FN macro.");
  TRI_LOG_FN (str);
}
The results are like below.
foo.cpp [7] : Creation of the foo object.
main.cpp [23] : Trivial logger in main().
main.cpp [24] : a = 1
main.cpp [25] : str = test
main.cpp [26] : p = ( PI, 3.1415 )
main.cpp [27] : q = ( 10, EUR )
main.cpp [33] : Test of the user-defined TRI_LOG_FN macro.
main.cpp (34) : str = test
main.cpp [12] : atexit()->finalize()->EXIT_SUCCES
foo.cpp [12] : Destruction of the foo object.
With that simple example we can learn that Trivial Logger:

Remarks:

  • Remember to put ";" after macro.
  • Macros are need to be defined because of debugging like style of logs, but if there is no need for such a style there can be defined pure functions for that purpose.

User-defined extensions

As example of extension can be considered simple logging function:
template < typename T >
void put_log_info ( tri_logger_t & log, T const & t )
{
  if ( log.is_activated() )
  {
     *(log.ostream_ptr()) << t << std::endl;
  }
}
The central point of the code is o use *(log.ostream_ptr()) as a raw pointer to the stream. Then any data can be sent there.
Good is to define macro similar to shown below, but it is not necessary if Logger will work all the time. And the second reason for defining macros is that in macros are available __LINE__, __FILE__ directives.
#define TRI_LOG_INFO(name) \
  trivial_logger::put_log_info ( trivial_logger::tri_logger(), (name) )

Library internals

Visual Studio configuration and tricks

To use CxxTL in Visual Studio there is need to copy nullstream.hpp, tri_logger.hpp and tri_logger.cpp files in to the proper project directory. Then this files have to be added to the project, by clicking on them and choosing "Import ...". To launch the Trivial Logger there is a need to add its flag to preprocessor invocation. On the screenshots below are shown examples what and where should be added. The "main" is a logger file name.
Preprocessor properties
Preprocessor properties
Preprocessor properties
Also is possible to add Trivial Logger to Managed C++ projects. However it needs to be added manually one line to the tri_logger.cpp file. Instead of:
#include "tri_logger.hpp"
Should be:
#include "stdafx.h"
#include "tri_logger.hpp"
Valid HTML 4.01 Transitional Valid CSS!