Boost logo

Boost :

From: John Eddy (johneddy_at_[hidden])
Date: 2005-02-15 19:20:54


Darren Cook wrote:

>> int main(int argc, char* argv)
>> {
>> my_log alog;
>> basic_log_manager<my_log > alm(alog);
>> alm.log(my_e_data(__FILE__, __LINE__, "Bad Operation"));
>> return 0;
>> }
>
>
> That is less scary than the earlier example. There is no way I'm going
> to type that out every time but I can do:
> #define LOG(x) alm.log(my_e_data(__FILE__, __LINE__, (x)))
>
> Hhmm, no, I've lost the ability to write:
> LOG("a="<<a<<",b="<<b);

You have lost it if you want to do it at entry creation time. If you
want, you can create a log that formats things that way as in the
"less-scary" example you are referencing.

>
> So I guess I define my macro based on your earlier example:
> #define LOG(x) alm.log(basic_entry<>("") \
> << boost::posix_time::microsec_clock::local_time() \
> << "," << __FILE__ \
> << "," << __LINE__ \
> << "," << BOOST_CURRENT_FUNCTION \
> << ":" << (x))
>
Yes, you could do that. However, if it is the only way you wish to
format your log entries throughout your application, it would be much
cheaper to have a custom log associated with a custom entry type as in
my example. The reason is that the basic_entry requires the creation
and usage of an ostringstream which is a fairly heavyweight object. It
all depends really on what you want x to be. If x were always going to
be a string literal for example, you could have instead:

#include <iostream>
#include <boost/current_function.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/logging/log_managers/basic_log_manager.hpp>

using namespace std;
using namespace boost::logging;
using namespace boost::posix_time;

struct my_e_data {
    const char* file;
    const char* fctn;
    int line;
    const char* text;
    my_e_data(const char* f, const char* fn, int l, const char* t) :
file(f), fctn(fn), line(l), text(t) {}
};

struct my_log {
   void log(const my_e_data& e) {
    // cerr or whatever.
      cerr << to_simple_string(microsec_clock::local_time())
             << "," << e.file
             << "," << e.line
             << "," << e.fctn
             << ":" << e.text << '\n';
   }
};

Then your macro could look like this:

#define LOG(tlm, x) tlm.log(my_e_data(__FILE__, BOOST_CURRENT_FUNCTION,
__LINE__, (x)))

(unless of course you have a global log called alm, as it seems you
would need to have by your macro, in which case you could omit the first
parameter).

This would be much, much cheaper and your usage would look like this:

my_log alog;
/*
doesn't have to be the basic manager and for that matter,
you don't really need to use a manager at all if you don't want. Your
macro would work
fine if you just passed it alog instead of alm b/c the interface for
logs is similar to that of managers in that they are both
required to have a log function taking a single parameter (an entry).
*/
basic_log_manager<my_log> alm(alog);
LOG(alm, "There is some problem in this application.");

> Darren
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost

Thanks,
John


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk