Boost logo

Boost :

From: Christian Holmquist (c.holmquist_at_[hidden])
Date: 2008-04-09 10:49:52

On 09/04/2008, vicente.botet <vicente.botet_at_[hidden]> wrote:
> Hi Christian,
> ----- Original Message -----
> From: "Christian Holmquist" <c.holmquist_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Monday, April 07, 2008 11:46 PM
> Subject: [boost] thoughts on logging library
> > Hi,
> >
> > I saw that the previously proposed logging library went into the
> > review queue again, so I thought of pointing out some remarks prior
> > the actual review.
> >
> > First of all, I think that a boost logging library should come up with
> > one, and one only, way of expressing a log line.
> >
> > BOOST_LOG(some, kind, of, args);
> >
> > Now, how should the interface of BOOST_LOG(...) look like? To find
> > that out, I'll start by explaining how I would like boost log to
> > behave from a users point of view, for instance using boost.Asio.
> >
> > #define BOOST_ASIO_LOG_MIN_LEVEL boost::log::level::debug
> > #include <boost/asio/asio.hpp>
> I'm not sure it is a good idea to place these macros in the source code
> files. First you can define the macros on several header files, needing some
> test undef and so one. Which will be the result when two source files (.cpp)
> defines different configurations? IMO the macros you purpose should be
> defined at the build level of the executable.

Of course.
It was only an example of the defines.

> I really think that we need runtime configuration and I suspect that this
> configuration should be centralized. But I don't think that this is a
> particular case of the logging library. logging and configuration are
> orthogonal. A runtime configuration library will be welcome and should be
> able to configure the asio log level as well as other configurable features
> as for example the boost::log::level of a global log.
> Let me show how I will use the current Boost.Log library interface if I were
> the maintainer of asio library.
> I will define un internal macro like that:
> if (boost::asio::log_level <= LEVEL) { \
> BOOST_LOG(LEVEL) << "[asio] " << MSG \
> }
> #else
> #endif
> I will place the definition of the boost::asio::log_level variable in a
> specific header file, which should be included by the user in only one
> comilation unit.
> // boost/asio/log_level_def.hpp
> #define BOOST_ASIO_LOG_LEVEL_DEFAULT boos::log::level::debug
> #endif
> #include <boost/asio/log_level_fwd.hpp>
> namespace boos {
> namespace asio {
> atomic_log_level_type log_level=BOOST_ASIO_LOG_LEVEL_DEFAULT;
> }
> }
> #endif

Sure, this could work, but I think asio::log_level should be a
function returning the current level instead of a global variable.
Then it's up to the user to choose where from this variable is read
and how it's updated. There may be more things to consider, again
something for a log library to decide best practice.

> As the boost::asio::log_level reading and writing could be done by different
> threads the read and write operations must be atomics. So
> atomic_log_level_type must be convertible to boost::log::level and must is
> assignable from boost::log::level atomically.
> typedef atomic<boost::log::level> atomic_log_level_type ;
> An other history is how can we configure the boost::asio::log_level variable
> at runtime?
> Well this can be done in a lot of ways. But at the end what you realy need
> is to do a the following
> boost::asio::log_level = new_value;
> Is for this raison that the atomic_log_level_type assignation operator must
> be atomic.
> We can use also a configurator class which store a mapping between some key
> and a reference of such variables.
> rtc::runtime_configurator<std::string, atomic_log_level_type&> conf;
> Note the mapped type is a reference to the real atomic_log_level_type.
> The advantage is that now the owner of the configured variable do not
> depends on how this variable is configured.
> It is up to the user to make the association between the configured variable
> and the configurator.
> This runtime_configurator could be based on the property_tree library.
> The user can add the configurable variables as follows
> conf.register("boost.asio.log_level", boost::asio::log_level);
> The runtime configuration library can provide a callable backdoor to
> configure any registered variable using cli, as for example
> $$ push boost
> $$ push asio
> $$ log_level = debug
> $$ log_level
> $$ pop
> $$ asio.log_level = debug
> $$ asio.log_level
> The push and pop command are used to change the context.
> the var = value command assign the value, and the variable command prints
> its value
> This backdoor will look up the corresponding configurable variable and read
> o write depending on the command.
> To allow symbolic values wee need manage with the conversion from
> std::string to boost::log::level and vice versa. We can use the lexical_cast
> library for this purpose as soon as the we have the output and input
> operators defined for boost::log::level.
> If the register is done at initialization time before the backdoor thread is
> lunched, the runtime_configurator instance will be used only for reads, so
> no thread safety problem at the map or tree_map level.
> Then the user can start the backdoor as follows
> boost::thread configurator_backdoor(rtc::backdoor)
> The user can provide its own external configuration means with a graphical
> interface if he consider convenient.
> Do you think that a such runtime configurator variables library has a place
> in Boost?

I haven't thought about it, but it sounds useful. It's probably an
often reinvented wheel.

> This could be a complement to a larger configuration library starting from
> program_options, extending to property_tree storage and making the CLI a
> specific parser, other parsers can be reading from some configuration file
> formats, the backdoor I'm proposing or other as has been already proposed in
> this mailing list (CGI parameter parser).
> <snip>
> > Configuring the above with a compiled library like boost serialization
> > is an interesting task as well, that I definitely think should be
> > addressed. could be that the flexibility decreases some in such a
> > scenario, or it could be configued in site-config.jam or whatever.
> Once the serialization library provide traces or log, if you want to use the
> serialization library with logs you should add a define at compile time
> e.g. -DBOOST_SERIALIZATION_LOG_ENABLE and link with the serialization logged
> variant e.g. -lboost_lserialization.

Agreed. Should the maintainer of serialization invent his own
build/jam/config thingie to make this possible? I think not.

> > Is this along the line what boost.log has in mind, or will it be a
> > logging library not to be used by the boost libraries themselves?
> I think that this has nothing to be with the Boost.Log library. It is up to
> the other Boost libraries to use or not the loging library.

Sorry, I disagree, I think that it has everything to do with the log library.
It should show how boost libraries should use the library to make them
customizable for end users of boost.

> The single flaw is that these libraries either must use a single global variable log or
> extend their interface with a log parameter. This problem has already been
> discused during the Boost.Singleton review.

Some boost libraries already use singletons. Religious views on
globally accessible data aside, what would be the flaw with a single
log instance?

> >
> > Regards,
> >
> > Christian
> Do you think that this approach allows to configure the libraries using the
> log library?
> Best regards
> _____________________
> Vicente Juan Botet Escriba
> _______________________________________________
> Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at