Logging macros (stdout or log4cplus)

c++ - December 2, 2016 - 13:06
  # l_log options

- L_NO_TRACE : disable all trace
- L_USE_LOG4CPLUS : use log4cplus instead of stdout or stderr
- L_DBG_NO_DUMP_ARGS : disable debug dump of args
- L_PREFIX : string used as prefix for macro (logger name for log4cplus)

# l_log API macros

- L_DBG(x) : debug
- L_DBG_FTRACE() : in/out debug trace in functions (use only once per function as first instruction)
- L_INF(x) : info
- L_ERR(x) : errror
- L_INIT() : initializes log4cplus
- L_DBG_DUMP_ARGS_0() : print function name
- L_DBG_DUMP_ARGS_1(a) .. L_DBG_DUMP_ARGS_5(a, b, c, d, e) : print variable(s) name and its value

/*
 * l_log.h
 *
 *  Created on: 30 mai 2012
 *      Author: Ludo
 *
 *  Updated on: 2016-12-03
 *      Author: Ludo (Ludorg ludorg[at]ludorg[dot]net)
 * 
 */

// l_log options
// L_NO_TRACE
// L_USE_LOG4CPLUS
// L_DBG_NO_DUMP_ARGS
// L_PREFIX

// l_log API
// L_DBG(x)
// L_DBG_FTRACE()
// L_INF(x)
// L_ERR(x)
// L_DBG_DUMP_ARGS_0()
// L_DBG_DUMP_ARGS_1(a)
// L_DBG_DUMP_ARGS_2(a, b)
// L_DBG_DUMP_ARGS_3(a, b, c)
// L_DBG_DUMP_ARGS_4(a, b, c, d)
// L_DBG_DUMP_ARGS_5(a, b, c, d, e)
// L_INIT()

#ifndef L_LOG_H_INCLUDED
#define L_LOG_H_INCLUDED

#ifndef L_PREFIX
#define L_PREFIX "l_log"
#endif

#ifndef L_NO_TRACE

// for Visual Studio
// cl /DL_PREFIX=\"hextor\" main_log_test.cpp
#ifdef _MSC_VER
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif

#ifdef L_USE_LOG4CPLUS

// tested with bash ubuntu for windows (gcc -v) gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
// -std=c++11 is required by log4cplus !!
// g++ -std=c++11 -DL_PREFIX=\"hextor\" -DL_USE_LOG4CPLUS main_log_test.cpp -llog4cplus

#include <log4cplus/log4cplus.h>

#define L_DBG(x) LOG4CPLUS_DEBUG(log4cplus::Logger::getInstance(LOG4CPLUS_TEXT(L_PREFIX)), x)
#define L_INF(x) LOG4CPLUS_INFO(log4cplus::Logger::getInstance(LOG4CPLUS_TEXT(L_PREFIX)), x)
#define L_ERR(x) LOG4CPLUS_ERROR(log4cplus::Logger::getInstance(LOG4CPLUS_TEXT(L_PREFIX)), x)

#define L_INIT()                        \
    log4cplus::Initializer initializer; \
    log4cplus::PropertyConfigurator::doConfigure(L_PREFIX ".properties");

#else // not(L_USE_LOG4CPLUS)

#include <iostream>
#define L_DBG(x)                              \
    std::cout << L_PREFIX << ":debug> " << x; \
    std::cout << std::endl
#define L_INF(x)                             \
    std::cout << L_PREFIX << ":info> " << x; \
    std::cout << std::endl
#define L_ERR(x)                              \
    std::cerr << L_PREFIX << ":error> " << x; \
    std::cerr << std::endl
#define L_INIT()

#endif // L_USE_LOG4CPLUS

namespace l_log
{
class in_out_func_logger
{
    const char *name_;

  public:
    in_out_func_logger(const char *name) : name_(name) { L_DBG(name_ << " >>>IN>>> "); }
    ~in_out_func_logger() { L_DBG(name_ << " <<OUT<<< "); }
};
}

#define L_DBG_FTRACE() l_log::in_out_func_logger _l_log_iof_logger(__PRETTY_FUNCTION__)

#else
#define L_DBG(x)
#define L_DBG_FTRACE()
#define L_INF(x)
#define L_ERR(x)
#define L_INIT()

#endif // L_NO_TRACE

#ifndef L_DBG_NO_DUMP_ARGS
#define L_DBG_DUMP_ARGS_0() L_DBG(__PRETTY_FUNCTION__);
#define L_DBG_DUMP_ARGS_1(a) L_DBG(__PRETTY_FUNCTION__ << " [" << #a << "=" << a << "]");
#define L_DBG_DUMP_ARGS_2(a, b) L_DBG(__PRETTY_FUNCTION__ << " [" << #a << "=" << a << " ; " << #b << "=" << b << "]");
#define L_DBG_DUMP_ARGS_3(a, b, c) L_DBG(__PRETTY_FUNCTION__ << " [" << #a << "=" << a << " ; " << #b << "=" << b << " ; " << #c << "=" << c << "]");
#define L_DBG_DUMP_ARGS_4(a, b, c, d) L_DBG(__PRETTY_FUNCTION__ << " [" << #a << "=" << a << " ; " << #b << "=" << b << " ; " << #c << "=" << c << " ; " << #d << "=" << d << "]");
#define L_DBG_DUMP_ARGS_5(a, b, c, d, e) L_DBG(__PRETTY_FUNCTION__ << " [" << #a << "=" << a << " ; " << #b << "=" << b << " ; " << #c << "=" << c << " ; " << #d << "=" << d << " ; " << #e << "=" << e << "]");
#else
#define L_DBG_DUMP_ARGS_0()
#define L_DBG_DUMP_ARGS_1(a)
#define L_DBG_DUMP_ARGS_2(a, b)
#define L_DBG_DUMP_ARGS_3(a, b, c)
#define L_DBG_DUMP_ARGS_4(a, b, c, d)
#define L_DBG_DUMP_ARGS_5(a, b, c, d, e)
#endif

#endif /* L_LOG_H_INCLUDED */

////// Usage example

#if 0

// g++ -std=c++11 -DL_PREFIX=\"hextor\" -DL_USE_LOG4CPLUS main_log_test.cpp -llog4cplus

// cl /DL_PREFIX=\"hextor\" main_log_test.cpp



#include "l_log.h"

int do_nothing(int a)
{
    L_DBG_FTRACE();
    L_DBG_DUMP_ARGS_1(a);
    L_DBG_DUMP_ARGS_0();
    return 0;
}

int main(int argc, char** argv)
{
    L_INIT();
    L_DBG_FTRACE();
    L_INF("starting");
    L_DBG_DUMP_ARGS_2(argc, argv);
    L_DBG_DUMP_ARGS_3(argc, argv, argv[0]);

    do_nothing(3);

    L_INF("done");

    return 0;
}

#endif