#130 optional in-memory logging support?

Util (6)


I am currently looking for a library that provides debugging support for basically ALWAYS LOGGING a configurable amount of data (say 1-5 MB) to an in-memory buffer in a FIFO fashion (possibly in a dedicated logging thread), but only actually display/store this data once an exception is thrown.

Sort of like a "poor man's backtrace". I am looking for a way to include very verbose information (timestamp, source file, function/method, line number, type of error, message etc) in these logs, so that segfaults can be more easily reproduced. At the moment, I am considering to use an XML/RDF based dialect for storage - but I would consider other solutions, too.

Would poco be suitable for this, or could it possibly be adjusted accordingly?

Thank you very much in advance

  • Carlos


  • Andy Mattice
    Andy Mattice

    Look in the Foundation Test projects.

    LoggerTest makes use of an std::list based in-memory channel known as "TestChannel" fromTestChannel.h/cpp.

    The implementation is short and sweet, and can easily beadapted to use a different underlying container if std::list doesn't provide the exact behavior you're looking for.


  • Andy, thank you very much for your help - exactly what I was looking for!

    • Carlos
  • Andy Mattice
    Andy Mattice

    Also consider this for adding FILE, LINE and FUNCTION...

    Not sure about the tradeoffs, but this is about the simplest I could come up with that still performs well, doesn’t execute when the priority puts it out of scope and is not monolithic...

    define logError( logger, msg ) \

    poco_error( (logger), FileLineFunction( (msg), FILE, LINE, FUNCTION ) )

    const char * g_version = "";

    std::string FileLineFunction( std::string msg, const char file, int line, const char func )
    std::stringstream msgStream;
    msgStream << msg
    << "\tFile: " << file
    << "\tLine: " << line
    << "\tFunction: " << func
    << "\tVersion: " << g_version;
    return msgStream.str();

    The idea above is to call the “logError” macro which will build into the compiled code a call to the simple “FileLineFunction” method to actually append those strings and line number at runtime.

    If the underlying call to Poco’s own “poco_error” resolves that the priority is right, then and only then will the method “FileLineFunction” get invoked.

    I put a breakpoint inside the function “FileLineFunction”, and it of course gets hit when the priority of the logger is set to Error, but if I limit the priority of the logger to Critical, then the breakpoint in “FileLineFunction” never gets hit.


    // testLogger.setLevel(Poco::Message::PRIO_ERROR);
    logError( testLogger, "My Error Message");

    So when it does fall within the right priority scope, the resulting message is…

    My Error Message File: .\Logger_example.cpp Line: 77 Function: wmain Version:

    By passing that message, then the default built-in PatternFormatter can take over and add the thread, date, processID and whatever else you would want to configure (configure when initializing the log channel).

    The alternative is to add it to customize the PatternFormatter so it takes those properties, but you would still need to get them loaded in the macro. You can imagine there would be an overloaded macro for every priority-specific poco macro (logWarning to poco_warning, etc.)


  • Andy, thank you again very much for your help. Yes, I was already planning to use preprocessor macros for this.

    I have another question though: Would you happen to know if there is any support in poco for providing an abstract wrapper on top of log messages that handles i18n, as well as categorization of log messages?

    Let me clarify:

    Ideally, I am looking for something that would allow me to maintain a log message specific ID (i.e. 32 bit integer) with a pointer to a std::map<LANGUAGE, std::string=""> so that I can associate each ID with a log message.

    The idea is to not only print just a very verbose and informative message (info, warning, error, exception), but also provide a unique message specific identifier. So that users can use this identifier for searching the product's knowledge base for additional info, without having to use an error-prone full text search in the KB system.

    By default, all log messages would be English, if the locale setting of the app matches a translated string, that would be shown instead - but regardless of the language being used, there would always be a "message identifier" prepended to all messages.

    I was thinking of assigning each log component/subsystem a unique pool/range of IDs, e.g. "database :3000-4000, network: 4000-5000, GUI: 5000-6000, compression: 6000-7000"

    Please do let me know if you think my thinking is way off

    Thanks again

    • Carlos
  • You can use the new macros in 1.3.7 (poco_information_f1(), etc.). These also include FILE and LINE. For localization, use one of the configuration classes in Util. You can then read a localized format string from the configuration file. 1.3.7 also allows for positional arguments in the format string (e.g.: %[1]d %[0]d), which is useful for localization.

  • bqJPA6 klqgaavbetgd, [url=http://hbzecpgfxloj.com/]hbzecpgfxloj[/url], [link=http://ountybetkill.com/]ountybetkill[/link], http://xtmkeianwvdw.com/

  • bTTLLg iyzulkhqdclb, [url=http://vtctbetimtjv.com/]vtctbetimtjv[/url], [link=http://cvodctvkqylm.com/]cvodctvkqylm[/link], http://fayfykejrzvp.com/

  • 7sHsgo gnoyepymgofq, [url=http://oefpsvmcuopy.com/]oefpsvmcuopy[/url], [link=http://vxpcohadjsts.com/]vxpcohadjsts[/link], http://rtejyncpqgxi.com/