
Hello Darren, I very much appreciate your feedback and will answer your questions as best I can. Darren Cook wrote:
I have continued working on a logging library as a possible contender for a new Boost library.
Hi, I just had a quick look. My usual logging needs are:
1. Being able to remove all logging code in a release build I see you have macros, though their names are long and it wasn't clear what all the different macros do (in examples/macros.cpp). Any issues in just doing a #define after including your headers to rename your macros into something short so I can simply write: LOG("In f, a="<<a<<",b="<<b);
You can easily remove all logging code from your release build by not defining BOOST_LOGGING_ON. If you do that, all the headers wind up doing nothing with the exception of the macro header which causes all the macros to expand to nothing. I agree that the macro names are long and a bit confusing. They all resolve to nothing if BOOST_LOGGING_ON is not defined with the exception of the BOOST_LOGGING_IF_OFF macro which I'm not sure is useful at all anyway. The difference between the various *LOG* macros is the ability to determine whether or not an entry will get logged before the entry is actually created. If that can be done (which it can using the macros) the process of logging in the case where it is common for log entries to be rejected can become much cheaper. If I continue to develop this as a possible boost library, I will of course accept suggestions for renaming the macros and anything else for that matter. I can see how something like BOOST_LOG() would be simpler than BOOST_LOGGING_LOG() etc.
2. Logging with timestamp automatically prefixed. Do you have something pre-built for this? If not, can you show what code I have to write to implement it.
There is a "helper" for automatically putting a timestamp into an entry. There are also a number of pre-existing entry types that are implementing that helper and of course, I can create any others that you might like. Below is an example of an entry that holds only a timestamp along with any other text supplied to it. The constructor of the entry takes a boost::posix_time::ptime object as the stamp (the default value is the current time) and any leading text that you wish to associate with the entry. /* * This example shows how to use the basic timestamp entry. */ #include <iostream> #include <boost/logging/logs/ostream_log.hpp> #include <boost/logging/entries/timestamp_entry.hpp> #include <boost/logging/log_managers/basic_log_manager.hpp> using namespace std; using namespace boost::logging; int main(int argc, char* argv) { ostream_log<> alog(cerr); basic_log_manager<ostream_log<> > alm(alog); alm.log(timestamp_entry<>("Hello. Its ") << timestamp_entry<>::stamp << ". Have a nice day." ); return 0; } If you wanted the timestamp to be the very first thing, simply don't supply anything to the timestamp entry constructor. ie timestamp_entry<>() instead of timestamp_entry<>("Hello...
3. Logging with file, line number and/or function name included.
I have not built the facilities for this yet but I certainly plan to do the file and line number at least. It is a fairly simple matter of creating the proper entry helpers and implementing some entry types that use them. I would like to note that anything "stream-outable" can be inserted to any of the basic_entry derivative types. The only thing that you get by using the helpers is that the entry will store the information (such as a timestamp) separately from the rest of the text so that it can be recalled. This is so that entries can be searched or otherwise differentiated based on their properties. Something as simple as the file and line numbers using the macros __FILE__ and __LINE__ could be inserted into any basic_entry right now so long as you don't wish to query for entries based on that information in your code. So if you are just printing this stuff to a file or other ostream or whatever and then forgetting about it (in code anyway) you could replace the above with: alm.log(basic_entry<>("Hello. Its ") << boost::posix_time::microsec_clock::local_time() << " and we're in file " << __FILE__ << " on line " << __LINE__ << ". Have a nice day." );
4. Logging to an in-memory buffer that only stores e.g. the last 50K or the last 100 log lines; with a function to output the log to an ostream. (i.e. I want to add LOG() lines are the start of each function, and at certain other key points, and then output a history trace when something asserts). Do you have anything like this? If not which current component would you suggest I use as a starting point to modify?
This would be a matter of creating a new log type. Currently I have implemented an ostream_log, file_log, list_log, appending_log, decorator_log, and null_log. These are all fairly simple and I see the need for many more log types. The only requirement of a log is that it have a method called log that accepts a single entry parameter. The method should probably be templatized but of course, it needn't be depending on the types of things you are logging. The log managers will accept the log type as the first template argument and use the log method when appropriate. To do what you want, I think you should plan to use the appending log with your custom buffered log and an appender (callback) to output to a stream - or the decorator log with your custom log as the first and an ostream log as the second. Then each entry as it comes in would be written into your custom log and then out to the ostream. The decorator is fairly simple to use. For example, here is a decorator for writing to cerr and to a file called "run.log". ostream_log<> olog(cerr); file_log<> flog("run.log"); decorator_log<ostream_log<>, file_log<> > dlog(olog, flog); basic_log_manager<decorator_log<ostream_log<>, file_log<> > > alm(dlog); Log whatever to alm as you normally would and it will wind up on standard error and in run.log. To actually do this right now I noticed that you will have to comment out the code in the constructor bodies of the file log. I am in the process of getting rid of the exception handling and so what's there won't compile.
Darren
current state is available for simple download from www.eng.buffalo.edu/~johneddy. It is not well Boost-ified yet but the
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost