0

I have the following system architecture (cannot be changed - legacy code): One main application invokes one or more other applications and these applications interact over a IP protocol.

All applications write to one console window. Unfortunately the console output can get messed up (one character from app 1, next char from app 2, next character from app 4 etc.). All applications write to console via one Logger.dll (provides static logging functions) using cout/cerr.

Is there a way how I can prevent mixed logging messages in this setup?

Thanks in advance.

EDIT code added:

void Logger::Log(const std::string & componentName, const std::string & Text, LogLevel logLevel, bool logToConsole, bool beep) 
{   
    std::ostringstream stream;

    switch (logLevel)
    {   
        case LOG_INFO:

            if (logToConsole) 
            {
                 stream << componentName << ": INFO " << Text;
                 mx_console.lock(); // this is a static boost::mutex
                 std::cout << stream.str() << std::endl;
                 std::cout.flush();
                 mx_console.unlock();
            }
            break;

       case LOG_STATUS: 

            stream << componentName << ": STATUS " << Text;
            mx_console.lock();
            std::cout << stream.str() << std::endl;
            std::cout.flush();
            mx_console.unlock();
            break;

       case LOG_WARNING:

            stream << componentName << ": WARNING " << Text;
            mx_console.lock();
            std::cout << stream.str() << std::endl;
            std::cout.flush();
            mx_console.unlock();
            break;

       default:;
     }

    if (beep)
         Beep( 500, 50 ); 
}
Simon
  • 1,616
  • 2
  • 17
  • 39
  • Can this Logger.dll be changed? – stefaanv Jan 16 '12 at 10:06
  • Yes, it's part of our project. It was introduced to avoid code duplication in every application. – Simon Jan 16 '12 at 10:08
  • Is your log output function multi-thread safe? If the text is mixed in your output console then it seems that it is not. You can use a mutex to guard your log function. – boto Jan 16 '12 at 10:18
  • If you buffer characters until there's a new line character, you can make the output significantly more readable as now you'll have entire strings mixed, not individual characters. – Alexey Frunze Jan 16 '12 at 10:19
  • @boto: the app can be thread-safe as in not crashing/hanging due to race conditions and such, but a console is a console. You have to order output to it somehow. – Alexey Frunze Jan 16 '12 at 10:21
  • The access to cout/cerr inside the logger function is locked by a static boost mutex. But I assume as there are multiple applications using Logger.dll, this mutex is not the same in every applications. – Simon Jan 16 '12 at 10:21
  • @Simon: If you create a mutex in your logger.dll (and really in that dll) then this mutex should be the same for all other parts of the programm using your logger.dll. Alex: I was talking about making the output creating function in that logger dll mutli-thread safe! – boto Jan 16 '12 at 10:26
  • @boto: I edited my question and added one of my logging function. However mutexing did not work. – Simon Jan 16 '12 at 10:30
  • @Simon: What is `mx_console`? Have you tried Windows named mutex? – wilx Jan 16 '12 at 10:34
  • it's a static boost::mutex, edited my question – Simon Jan 16 '12 at 10:35
  • @Simon: the trick is creating your logger instance really only once per entire application, i.e. you should have really only one single place in your app which creates and accesses your logger instance (your will need a kind of app-global proxy for accessing the logger instance). And lock the entire Log method not only the case-branches (in order to avoid intermixing of various log level outputs). – boto Jan 16 '12 at 10:36
  • Right now, Log() is static, because I wanted to avoid to create a logger instance in ever application. You are right locking only cases may not help – Simon Jan 16 '12 at 10:40
  • I just made the observation that outputs sent via printf() don't get mixed up at the console although there's no mutex at all. – Simon Jan 16 '12 at 13:24

3 Answers3

0

Since you have separate logging functionality you can at minimum use some kind of locking (global mutex, etc.) to avoid interspersing messages from different applications too much. To make it more readable and grepable, add some identifying information, like process name or PID. Wrapping your Logger.dll around existing logging library sounds like an option as well.

Alternatively, you could have logging functions just forward messages to your main application and let that to sort out the synchronization and interspersing.

wilx
  • 17,697
  • 6
  • 59
  • 114
0

Syslog might be a solution for you as it is intended to handle logs from various places. Syslog is developed for unix, but this answer shows versions for windows.

You can change your logger to log to syslog instead of the console.

Community
  • 1
  • 1
stefaanv
  • 14,072
  • 2
  • 31
  • 53
0

I replaced now all the

std::cout << stream.str();

statements with

std::string str = stream.str();
printf(str.c_str());

and now the output isn't messed up character-wise anymore. But I don't have a good explanation for this behavior, does anybody know why?

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Simon
  • 1,616
  • 2
  • 17
  • 39