Boost logo

Boost :

From: Andrey Semashev (andysem_at_[hidden])
Date: 2007-04-09 02:24:40


Hello Gareth,

Monday, April 9, 2007, 1:30:34 AM, you wrote:

> Andrey Semashev wrote:
>> Hello,
>>
>> I have a question about the logging attributes concept.
>>
>> I'm thinking now about the implementation of attributes, filtering and
>> sinks (in particular, formatting log messages in sinks) and I come to
>> a conclusion that we have to mandate the set of types that will be
>> used in the attributes<->logging library interface. The reason we have
>> to do this is that the library should be able to be compiled
>> separately from the user's code (i.e., in dll), which defines the
>> attributes. It doesn't mean, though, that the user won't be able to
>> define arbitrary types of attributes, but these types should be
>> representable in one of a predefined set of types.
>>
>> For now I see the following types set being suitable for this purpose:
>> - int
>> - unsigned int
>> - long long
>> - unsigned long long
>> - double
>> - std::string or std::wstring, depending on the library configuration
>> - boost::any. This won't be supported by the library's sinks out of
>> box and is aimed for extensibility on the users' behalf.
>>
>> I know such lack of generalization is not welcome, but I can't figure
>> out any other way to organize interaction between different dlls.
>> Maybe there are other opinions?
>>
>>
> I've been scratching my head about this. I'm currently trying a
> mechanism where you define a type (maskable) and all attributes need to
> be derived from that type. This way the filter can then apply a member
> from the maskable interface to determine if the message can succeed with
> this particular attribute.... Also there would be a member to convert
> to_string.

> So you could define a type:

> class line_number : public maskable
> {
> int l;
> ...
> };

> then define your filter

> class my_filt : public filter
> {
> bool pass(line_number& line)
> {
> return line.l > my_threshold;
> }
> };

> This would necessitate a constraint (every type you use for an attribute
> must derive from maskable) but then that's part of the framework that I
> cant see how to avoid.

The necessity to derive attributes from the common base class exists
either way, but it doesn't solve the problem.

You see, in your example the filter would get "maskable& line", not
"line_number& line" as the logging library doesn't know about
"line_number" class. This means that you will have to make some type
dispatch to get the real attribute type, and I'm afraid this will be
a performance killer.

Other two problems here are:
1. I believe the "to_string" member function you mentioned (I guess,
you meant to use it to format sinks' output) should not be a part of
attribute. I should be a sink's implementation detail (and in fact, it
may be customizable). For example, a date that is initially
represented as time_t, may be differently formatted as string by text
sinks and may be dumped into file as int by binary sinks.
2. I would like filters to be as much independent from attributes
as possible. IMO, in real applications the filters will be generated
in very different places (and maybe modules) than the attributes and
often they will not even know real attribute's type. In your example,
imagine the "my_filt" doesn't know that "line_number" exists.

-- 
Best regards,
 Andrey                            mailto:andysem_at_[hidden]

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