Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing a log stream in C++ in a cout-like notation

I have a class in c++ in order to write log files for an application of mine. I have already built the class and it works, it is something like this:

class Logger {
   std::string _filename;
public: 
   void print(std::string tobeprinted);
}

Well, it is intuitive that, in order to print a line in the log file, for an object of Logger, it is simply necessary to do the following:

Logger mylogger("myfile.log");
mylogger.print(std::string("This is a log line"));

Well. Using a method approach is not the same as using a much better pattern like << is. I would like to do the following:

Logger mylogger("myfile.log");
mylogger << "This is a log line";

That's all. I suppose I must overload the << operator... But overloading using this signature (the classic one):

ostream& operator<<(ostream& output, const MyObj& o);

But I do not have a ostream... So, should I do as follows?

Logger& operator<<(Logger& output, const std::string& o);

Is this the right way? Thanks

like image 735
Andry Avatar asked Dec 30 '10 13:12

Andry


People also ask

How do you log information in C++?

The C++ compiler has two very useful defines for logging: the __FILE__ and __LINE__ defines, which contain the name of the file and the line in which they are placed and can help you track down the location of the error. Because I am using the compiler define, they are automatically inserted into the correct place.

How does cout works?

The cout object in C++ is an object of class ostream. It is defined in iostream header file. It is used to display the output to the standard output device i.e. monitor. It is associated with the standard C output stream stdout.

Is cout an operator?

cout is an object of the output stream that is used to show output. Basically, cin is an input statement while cout is an output statement. They also use different operators. cin uses the insertion operator( >> ) while cout uses the extraction operator( << ).


1 Answers

class Log
{
public:

    enum Level { Debug, Error, Info };

    static ostream& GetStream() { return cout; }
    static bool IsLevelActive(Level l) { return true; }
};

#ifndef NO_LOG
#define LOG_ERROR(M)   do { if (Log::IsLevelActive(Log::Error))   (Log::GetStream() << "ERR: " << M << "\n"); } while (false)
#define LOG_INFO(M)    do { if (Log::IsLevelActive(Log::Info))    (Log::GetStream() << "INF: " << M << "\n"); } while (false)
#define LOG_WARNING(M) do { if (Log::IsLevelActive(Log::Warning)) (Log::GetStream() << "WRN: " << M << "\n"); } while (false)
#else
#define LOG_ERROR(M)
#define LOG_INFO(M)
#define LOG_WARNING(M)
#endif

struct MyObject {
    int a, b;
};

ostream& operator<<(ostream& ostr, const MyObject& obj) {
    ostr << "(a=" << obj.a << ", b=" << obj.b << ")";
    return ostr;
}

void test() {
    int v1 = 42;
    int v2 = 43;
    LOG_INFO("value1=" << v1 << ", value2=" << v2);

    MyObject o = {1, 2};
    LOG_INFO("obj=" << o);
}
like image 93
rlods Avatar answered Nov 14 '22 22:11

rlods