2

I wrote this logger. It works fine, but there is something I have not been able to do.

uLOG(warning) << "Test log message " << 123 << uLOGE;

uLOG locks a C++11 mutex and starts writing on a file stream.
uLOGE flushes the stream and unlocks the mutex.

I would like to get the same result with this syntax:

uLOG(warning) << "Test log message " << 123;

so I would like the flush and the unlock to be called automatically at the end of the line.

Which is a possible way to do it?

  • I tried setting the ios::unitbuf flag, but this forces a flush for every << operator, not ideal for an SSD wearing. And it does not unlock the mutex.
  • I tried defining a temporary object in uLOG whose destructor would flush and unlock, but that forces to put the log line in its own code block: { uLOG(warning) << 123; }

Reference

Community
  • 1
  • 1
Pietro
  • 12,086
  • 26
  • 100
  • 193
  • The braces in the second example aren't necessary, why do you think they are ? :) that might be the real issue – OMGtechy Mar 14 '17 at 15:53
  • @OMGtechy: I put the braces so that the temporary object goes out of scope and its destructor is called. – Pietro Mar 14 '17 at 15:56

2 Answers2

5

You need to redesign your logging framework, so that uLOG is a class that you instantiate, and whose destructor does the work of your uLOGE macro.


Very simple example:

struct uLOG
{
    uLOG(std::string const& type)
    {
        std::cout << "Log: " << type << " - ";
    }

    template<typename T>
    uLOG& operator<<(T const& output)
    {
        std::cout << output;
        return *this;
    }

    ~uLOG()
    {
        std::cout << " (end of log)" << std::endl;
    }
};

// ...
uLOG("warning") << "log message" << 123;

The above, in a suitable program, should print

Log: warning - log message123 (end of log)

This solution should not require the use of braces, so could be used in a single-statement un-braced if or loop.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

Your second approach is correct, if implemented correctly it does not require braces. Did you do it with macros? They are not needed here.

uLOG should be a function that returns a temporary object of a Log writer class. As you outlined, it should lock in ctor and flush and unlock in dtor and also have templated operator<< for all types, that just forwards the call to actual log destination.

Peter K
  • 1,787
  • 13
  • 15