
On Sat, 27 Dec 2008 21:02:51 -0500, Emil Dotchevski <emildotchevski@gmail.com> wrote:
[snip] My point was that I think it's better to leave it up to the user to deal with the condition "manually", as in if( logging::warnings ) log << "Warning"; or if( logging::warnings && logging::severity>10 ) log << "Severe warning"; or even if( logging::warnings ) { log << "Warning"; if( logging::severity>10 ) log << "Severe warning"; } That way the logging library only needs to expose two independent interfaces, one that provides the "log" object (which is just a std::ostream &) and another that provides convenient compile-time or run-time flags for users to type in if statements as above.
One of the projects I deal with can generate several hundred MB of logs over the course of a day if we have logging cranked up. We log both as an light audit trail and a debugging tool. Dealing with that much information can become rather difficult. There are a few things that come to mind that I would change in it: 1) When reading the code, logging should scan like a comments-- they should be readable and informative but ignorable. A lot of logic, conditionals, or even excessive formatting distracts from figuring out what a function actually does. Severity (debug, warning, error, etc) is only one dimension, though the most common. If I add new dimensions, how much does that affect complexity of the conditionals? What are the chances of mistyping one of the conditionals and not getting a logging message? 2) The logging output needs to be well formatted, readable, and broken up into manageable pieces. Imagine getting a packet or request in, then having to dump it. Does it show up as one or two records? Does it end up on a 500 character wide line? How much overhead should one add to the site of the logging call to format this? If I split my files into an log file that contains everything and an audit file that only contains some, should the formatting be the same? What if I want to merge them at a later time, do I need to edit everything and recompile? What if I want to change output and direction at runtime? Do I think of all of that in the function, or do I configure the logging and just let it fly? The former implies that there should be an abstraction around the logic of whether a record gets logged. The latter implies an abstraction around formatting and how to determine the destination of the record. That and a few extra bows is the extent of what I'm trying to do. -- Jason Wagner jason@nialscorva.net