Boost logo

Boost :

From: Darryl Green (darryl.green_at_[hidden])
Date: 2004-11-01 21:51:27


Caleb Epstein <caleb.epstein <at> gmail.com> writes:

> Take for example the ACE_Log_Msg structure from the ACE library (just
> the important bits):
>
> class ACE_Log_Msg { [...]
> // Status of last operation (user defined)
> int status_;
> // errno when this message was created
> int errnum_;
> // Line number in file_ where the message was generated
> int linenum_;
> // Name of file where message was generated
> char file_[MAXPATHLEN + 1];
> // The message itself
> char msg_[ACE_MAXLOGMSGLEN + 1];
> // Pointer to thread descriptor
> ACE_Thread_Descriptor* thr_desc_;
> // Priority (severity) of this message
> unsigned long priority_mask_;
> // Name of the program
> static const char* program_name_;
> // Hostname
> static const char* hostname_;
> };
>
> No judgements of relative goodness/badness, just for informational
> purposes. I would also suggest that any structured log message
> contain a timestamp indicating when it was generated.

I'm not clear on your point here - do you/have you used the ACE logging
facilities? What feature do you actually want, if any, from there?

I certainly don't want a logging lib that collects "interesting stuff" on
the off-chance that some output formatter might use it (and there have already
been complaints about coupling - something like this is going to make it worse).

If what you want is something like the ability to have a modifier add this sort
of information to the message, it already exists. The only question is, in what
form is the message and the data added by the modifier? There is nothing
stopping you from (for example) putting XML into the message, and having the
modifiers add additional elements, then having an xml processing appender
pick/chose and format these elements. Now, that sounds like overkill, but in
some systems that may be a great idea, because the appender is actually just
chucking this data in a file, or across a network, and some log
view/query/filter tool can process the XML any way it likes. A lighter-weight
version might just put attrib=value entries into the message, with newlines
separating them or... If that isn't enough, as I've said before, it is possible
to have some completely custom "string" and "stream" if that works for you.

Maybe what is really missing is a clear set set of requirements the libary
needs to address. FWIW I think the following is a reasonable set, without
ending up with an everything including the kitchen sink result:

The library must provide a logging framework with a fairly minimal, portable
set of facilities with few dependencies. Exactly what those facilites should be
may need some refinement, but the ability to produce logfiles in some
conventional, useful ways (including cyclic) and formats, and the ability to
easily output arbitrary data to the log (which pretty much means a streams
interface?) would seem to be the absolute minimum.

The logging library must be very efficient in handling disabled "logs".

The logging library must be user extensible to add new output (appender)
facilities. This should be very easy and not require in-depth knowledge/study
of library/its docs to do. Appenders, which are likely to have system
dependencies, should not be tightly coupled with the core logging facilities.

The logging library must be user extensible to add new modifier facilities.
This should be very easy and not require in-depth knowledge/study of
library/its docs to do. Modifiers, which are likely to have system
dependencies, should not be tightly coupled with the core logging facilities.

The library must scale well. This should include the ability to (efficiently)
use a very minimal form of the library in small, perhaps single-threaded only,
apps as well as achieving good performance on multiprocessor platforms in
multithreaded apps.

The above points cover basic, portable usage. However, there are many
environments where more customisation is needed, possibly non-portably. Making
some components of the library generic can address this, but beyond some
(possibly useful in their own right) example/test cases, I don't think actual
implementations of a wide variety of these options need be included in the
library, though over time it could be extended with additional submissions.

Customisable Configuration/control of log enabled/disable, which appenders
particular logs write to etc. One general purpose way of doing this at least
must be provided.

Customisation of the form in which log information is provided to the log.
As per earlier requirements, a stream interface at least must be provided.
Another interface, perhaps one allowing some form of arbitrrary attribute/value
entry might be provided at least as an example.

Customisation of the form in which log messages are transported to
modifiers/appenders. Currently the lib uses std::string for this. Perhaps a more
highly tuned type could be provided by default - one where modifiers
directly/efficiently prepend (as well as append) through a stream interface
would be useful. Appenders really only need to receive a character iterator
range. However, more wildly different types should be possible and at least an
example provided (eg. some form of sequence of attribute/value pairs - maybe a
map<std::string,boost::any> would be a good example?).

I actually think the current proposal goes a long way towards meeting all of
these (there are some areas that need "fixing" but I think the basic design is
there). Are there any other design issues that need to be resolved or is it only
a case of the implementation having a few gaps/bugs?

Regards
Darryl.


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