Boost logo

Boost :

From: Johan Nilsson (johan.nilsson_at_[hidden])
Date: 2004-11-04 04:09:53


Hi,

I've been thinking (yes) and am now taking a 180-degree turn on my previous
standpoints in this discussion:

I propose that John's Boost.Log library should remain basically as-is -
*but* - should be moved into e.g. boost::text_log instead. The library
should be renamed to reflect that (can't think of a really good,
pronouncable name). Why ... well here are some points :

- The library is in its current state extremely flexible due to the
text-based manipulation.
- Even though flexible, it is still easy to use and extend.
- Many people (everyone except me?) seems to be happy with text-based
logging.
- Performance of using streams in the interface (in the caller's context)
seems to be ok with everyone, as long as logging to the specific log can be
turned off.
- It's all-in-all kind of beautiful in it's simplicity and ease of use.
(Did I say that it was flexible?)
- Fast compile times (as said earlier)
- ... etc ...

I'd even go so far as to say that the current implementation is too general
(log_manager concept etc). Why not make it even simpler and only put in some
effort to make the threading support more loosely coupled (as is already in
progress). I'd definitely like light-weight Win32+Posix compatible
integrated threading support. Keep the naming (and concepts +
implementation) simple and concrete: e.g. strings, streams, a single log
manager implementation and just stick to that to make it clear what the
library actually does.

I'd personally very much like some kind of structured logging functionality,
and I'll probably work on that offline in the near time. I'll keep the
discussions (including requirements) from here in mind and post to the list
when (and if) I come up with something useful. Any interest?

So why did I take this turn? Basically, because structured logging and the
kind of flexibility provided by John's implementation doesn't mix well. I
don't want to complicate things for the rare occasions where people really
*need* structured logging. There are ways to implement structured logging
and extensibility in what's logged; I though about using the extension
object pattern[1], but it has a certain performance impact - especially in
the single-threaded environment.

I'm currently leaning towards a (hybrid?) approach where logs are
parameterized on
their log_item type, but the log_item type would always derive from a
basic_log item - that provides the extensibility should it be needed in the
(few) cases. Formatting should still be based on message ids + insertions
and left off to execute in the background.

Sorry for stirring up all this, but I hope that it at least gave some feed
for thought ;-)

Regards // Johan

---
[1] Brief example for the extension objects idea (pseudo pseudo-code):
struct log_item_extension {};
struct log_item
{
    typedef /* implementation defined */ ext_id;
    void add_extension(ext_id, const log_item_extension& p_ext);
    const log_item_extension& extension(ext_id) const;
}
struct time_stamp
: log_item_extension
{
    time_stamp()
     : m_ts(get_timestamp())
    {}
    const /* impl-defined */& ts() const;
private:
    /* impl-defined */ m_ts;
};
struct severity
: log_item_extension
{
    severity(int value)
    : m_value(value)
    {}
    int value() const
    { return m_val; ]
private:
    int m_val;
}
.....
void init_logs()
{
    app.add_modifier(time_stamp());
    syslog.add_modifier(severity());
    ...
    syslog.add_appender(event_log_appender());
}
...
void event_log_appender::operator()(log& log, const log_item& log_item)
{
    try
    {
        const severity& sev =
dynamic_cast<severity&>(log_item.extension(severity::id()));
        const source& src =
dynamic_cast<source&>(log_item.extension(source::id()));
        ... etc ...
    }
    catch (boost::log::bad_extension& be)
    {
        assert(be.what());
    }
}
----

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