Boost logo

Boost :

Subject: Re: [boost] [log] Review-ready version in the Vault
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2009-02-12 15:01:07


vicente.botet wrote:

>>>> He does need to open a record in some way. Opening a record is not only
>>>> filtering, although this is a part of the process. The key point of
>>>> opening a record is acquiring values of all attributes and composing
>>>> them into a single view. It is this view then processed by filters,
>>>> formatters and sinks.

>>> I desagree in this pooint.

>> You cannot execute the filter without having a view of attribute values
>> because the filter makes its decision based on this view. Do you have
>> something different on your mind?
>
> Why not making the filter just in a view of attributes values, not the record itself. If I have understood, the library do not proposse firter on log records.

I'm sorry, you're losing me here. Could you rephrase your suggestion,
please? A pseudo-code snippet would be helpful.

>>>> All these cases are covered by stream manipulators and operator<<
>>>> overriding. I must say, this approach is much more appealing than
>>>> writing inline loops etc., since it may be reused regardless of logging.
>>> This was just an example. You will need to inline loops on the operator<< overriding, isn't it?
>> Yes, but these manipulators or operator<< overloads can be reused.
>
> Sorry, I don't undesrtand. Could you elaborate on that.

You could have something like this:

   template< typename RangeT >
   struct range_manip_t
   {
     RangeT& range_;

     template< typename CharT >
     friend std::basic_ostream< CharT >&
     operator<< (
       std::basic_ostream< CharT >& strm,
       range_manip_t const& r)
     {
       std::for_each(
         begin(r.range_),
         end(r.range_),
         var(strm) << _1);
       return strm;
     }
   };

   template< typename RangeT >
   range_manip_t< RangeT > range_manip(RangeT& r)
   {
     return range_manip_t< RangeT >(r);
   }

Now you can use it with any ranges and streams, including logs.

   std::list< int > l;
   std::vector< std::string > v;
   boost::iterator_range< double* > r;

   std::cout << range_manip(l);
   std::wostringstream wss;
   wss << range_manip(v);
   BOOST_LOG(lg) << range_manip(r);

>>>> That looks much more attractive. However, I had something like this in mind:
>>>>
>>>> if (log_record rec = lg.open_record())
>>>> {
>>>> rec.strm() << ...;
>>>> }
>>>>
>>>> The one problem I see here is how to deduce the log_record type from lg.
>>>> I don't want to use Boost.TypeOf since it looks too heavy to me.
>>> What about defining it inside the logger?
>>>
>>> logger_type lg;
>>> if (logger_type::scoped_log_record rec = lg.open_record())
>>> {
>>> rec.strm() << ...;
>>> }
>> The problem is that I don't have logger_type in the BOOST_LOG(lg) macro.
>
> The BOOST_LOG macro is another issue. When you use the BOOST_LOG you can state this macro push a log record, and maybe you will need to use the current interface. My concern is that the application must be able to master the log record delimiter, not that this must be done on the macro.

Well, I'd like the library interface to be as consistent as possible.
I'll have to think more on this.


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