
Beman Dawes <bdawes <at> acm.org> writes:
But a dependency on any thread library is likely to throw cold water on my use. Here are the likely scenarios:
* Light-duty uses in light-duty non-multithreaded programs, where introducing a threading dependency seems far too heavy-weight for the apps.
There really isn't one in this case - see below.
* Heavy-duty industrial uses. I'm not adverse personally to a threading library dependency for these apps (which are sold as libraries); , but I'd have to get permission from managers who will be very concerned about use of a threading library clashing with customer's use of other threading libraries. Whether these concerns are valid or not is almost beside the point; it will be a hassle.
The library actually supports overriding the types used for logging including the threading primitives used, which (unless you use the ts_appender) is only a simple mutex and corresponding scoped lock class. So you should be able to keep those managers happy by using/wrapping other mutex/lock classes.
... it would be nice if there was a basic subset of features that could be used without threading concerns.
There is. Much of this can be addressed by better docs, but there is still some level of flux in how the internals (including the types exposed to allow alternative implementations to be assembled) fit together, so detailed docs on the architecture might take a while to arrive. In the meantime: The lib can be broken down into: 1) The logger itself. Each log has a collection of appenders and modifiers and an enabled state. 2) A manager that maintains collections of loggers, appenders, modifiers, enabled state and provides methods for changing the logging settings. 3) A collection of appender and modifier functions. Each logger has a mutex to protect its state. The log manager uses a mutex to serialise updates. It still needs to be resolved how the actual writing (calling of modifiers and appenders) should occur in a multithreaded environment. I think it should be done with no lock held by the logger (or the manager). In that case the appender and modifier functions need to be threadsafe (reentrant) so stateful functors may need to use some form of locking. Note that that isn't how the lib is at present - the log manager lock is held during writing. In all the above, in a single threaded build, a null mutex type is used. There is also the case of appenders, such as the ts_appender, which internally use boost.thread, and that can only possibly run in a multithreaded environment. FYI, the manager is a concept, which curently has 1 implementation. The concept probably needs a bit of refinement (and docs), but the key point is that alternate managers can be used if needed. Other types, including the "string" and "stream" types can also be replaced. It should be possible to build at least the following logging systems with the library: 1) The lib as presented so far. 2) A very simple logging facility, with an essentially null manager - just providing an interface to manually bolt together loggers and appenders/mutators. One form of this might be a logging facility that can only have its settings changed (eg read from a file) by an app restart, in which case even in a multithreaded app most locking can be eliminated. 3) Something quite radically different such as a log where the "stream" is something into which structured log information can be assembled, and the "string" carries that information to appenders that use that structured information (format it for textual output, write it to a database table...). 4) ... Regards Darryl Green.