I implemented a Logger, so it can be used like ostream. e.g, if someone wants to write to the log - he can do something like this:
LOG << "hello world " << 6 << 8.6 << "\n";
The log will be written to the screen, to log file, and to any other source the user like to (this isn't the issue).
To achieve this goal, I created a macro for LOG:
#define LOG Logger::GetInstance()(__FILENAME__, __func__, __LINE__)
and overloaded operator () and operator <<:
template <typename T>
inline Logger& operator << (const T& msg) {
std::stringstream ss;
ss << msg;
PrintToFile(ss.str());
PrintToScreen(ss.str());
return *this;
}
Logger& Logger::operator () (const std::string& sourceFile, const std::string& funcName, int lineNumber) {
std::stringstream ss;
ss << Utilities::GetFormattedTime("%d.%m.%y %H:%M:%S") << "::" << sourceFile << "(" << lineNumber << ")::" <<
funcName << "::";
PrintToFile(level, ss.str());
PrintToScreen(level, ss.str());
return *this;
}
The problem is when I have more than one thread that is running over my process, the print may be cut, because of context switch between the threads in the middle of the example line above (LOG << "hello world... ")
Using a mutex may not help, because operator << and operator () are not the same function.
Is there any brilliant or simple solution for this problem?
Just from top of my head. If you want to keep your approach with stream io operators as is, you can use sort of proxy object that locks\unlocks mutex.
Please, don't draw attention to coding style (especially swfull and dangerous Logger implementation). Below you can find brief illustration of mentioned idea.