2

I wrote my own simple class for logging. I understand that I better to use some kind of library (boost.log, log4cpp?) but let's anyway discuss my simple class:

#include "stdafx.h"
#include "Logger.h"


Logger::Logger(std::string fileName)
{
    logFile.open(fileName);
}


Logger::~Logger(void)
{
    logFile.close();
}


void Logger::Error(std::string message) {
    logFile << message << std::endl;
}

void Logger::Debug(std::string message) {
    logFile << message << std::endl;
}
  1. I want my methods to accept variable number of arguments, so I can pass parameters like that "Error code: %x", code. How to do that?
  2. I want Debug method to be excluded if LOG_DEBUG compilation symbol is not set. in C# I can just add [Conditional("LOG_DEBUG")] before the method declaration, but now to do that in c++?

upd Regarding 1 i've tried that and it works:

void Logger::Debug(std::string message, ...) {
va_list arglist;
fprintf(pFile, message.c_str(), arglist);
Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • 1
    following two should help you http://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c and http://stackoverflow.com/questions/2506632/c-conditional-compilation – Hemant Nov 26 '12 at 12:08
  • @Caribou sorry i'm just starting learning c++ – Oleg Vazhnev Nov 26 '12 at 12:29
  • @javapowered no need to be sorry (I didn't dv this btw) Joachims answer is a good start. You could extend the Macros and add more params – Caribou Nov 26 '12 at 12:32
  • @Caribou I need some easy way to exclude at all any logging at Release build but to keep it in Debug build. I even don't want to have any "extra comparision" i really want compiler to just exclude logging cause I care about latency in Release build. – Oleg Vazhnev Nov 26 '12 at 12:42
  • @javapowered thats exactly what you can achieve with Joachims answer - if you have a test for Debug (or a #define of your choice) - if true then define as below, if not define LOG_DEBUG(logger, output) as empty - look up the preprocessor on google – Caribou Nov 26 '12 at 12:46

2 Answers2

5

The simplest way, in my opinion, is to use macros for this:

#define LOG_DEBUG(logger, output) \
    do { logger.getStream() << "DEBUG: " << output << std::endl; } while (0)

LOG_DEBUG(logger, "Some value = " << some_value);

This will allow you to use all the normal C++ stream manipulators.


As for the second part, it's simple preprocessor trickery too:

#ifdef DEBUG
# define LOG_DEBUG(logger, output) do { ... } while (0)
#else
# define LOG_DEBUG(logger, output)
#endif
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
4

I want my methods to accept variable number of arguments, so I can pass parameters like that "Error code: %x", code. How to do that?

You have two solutions for this:

  1. use printf-like formatting. This would require the usage of va_list, va_arg and va_end macros.

  2. use operator overloading (as in @Joachim's answer).

I want Debug method to be excluded if LOG_DEBUG compilation symbol is not set. in C# I can just add [Conditional("LOG_DEBUG")] before the method declaration, but now to do that in c++?

You define a logging macro, in two different ways, depending on DEBUG macro definition (or NDEBUG or something similar):

#ifdef DEBUG
#define LOGE(X) Logger::Error(X)
#define LOGD(X) Logger::Debug(X)
#else
#define LOGE(X) 
#define LOGD(X) 
#endif
utnapistim
  • 26,809
  • 3
  • 46
  • 82