$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [Log] Pre-review questions
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2010-03-14 15:00:42
On 03/14/2010 06:29 PM, Christian Holmquist wrote:
>
> Simple task 1
> I've two source level attributes, System and Severity. I wish to create a
> log macro that takes these two arguments.
[snip]
> The above is not a complicated scenario and I should be able to quickly find
> an answer. Maybe I've just missed it..:)
Well, depending on how you use the "System" attribute, you can take
either of the following approaches:
1. Use the severity_channel_logger. The severity attribute will handle
your severity levels, and the "System" attribute will be represented as
a channel. This means that you would have to have a logger per "System".
typedef src::severity_channel_logger<
SeverityLevel,
System
> my_logger_t;
my_logger_t lg_SYSTEM_A(keywords::channel = SYSTEM_A);
my_logger_t lg_SYSTEM_B(keywords::channel = SYSTEM_B);
BOOST_LOG_SEV(lg_SYSTEM_A, INFO) << "Hello";
If you want to, you can define your macro like this:
#define LOG(x, y, z) BOOST_LOG_SEV(lg_ ## x, y) << z
LOG(SYSTEM_A, INFO, "Hello");
2. If having several loggers is not an option, but the system attribute
is needed occasionally, you can add the attribute as a tag. The
technique is described here:
3. If the system attribute is needed all the time, then I might suggest
to develop a logger feature, pretty much like it is described in the
docs by the link I posted, but with one minor difference. The attribute
should be added to the logger on its constructor, and only modified on
the open_record call. Altering the example at the link, it should look
something like that:
template< typename BaseT >
class system_feature :
public BaseT
{
public:
typedef typename BaseT::string_type string_type;
typedef typename BaseT::attribute_set_type attribute_set_type;
typedef typename BaseT::threading_model threading_model;
typedef typename BaseT::record_type record_type;
shared_ptr< attrs::mutable_constant< System > > m_pSystem;
public:
system_feature() :
m_pSystem(new attrs::mutable_constant< System >(SYSTEM_A))
{
this->add_attribute_unlocked("System", m_pSystem);
}
system_feature(record_tagger_feature const& that) :
BaseT(static_cast< BaseT const& >(that)),
m_pSystem(new attrs::mutable_constant< System >(SYSTEM_A))
{
this->add_attribute_unlocked("System", m_pSystem);
}
template< typename ArgsT >
system_feature(ArgsT const& args) :
BaseT(args),
m_pSystem(new attrs::mutable_constant<
System
>(args[keywords::system]))
{
this->add_attribute_unlocked("System", m_pSystem);
}
typedef typename src::strictest_lock<
boost::lock_guard< threading_model >,
typename BaseT::open_record_lock
>::type open_record_lock;
protected:
template< typename ArgsT >
record_type open_record_unlocked(ArgsT const& args)
{
m_pSystem->set_value(args[keywords::system]);
return BaseT::open_record_unlocked(args);
}
};
> Simple task 2
> Create a custom filter without using any Lambda magic.
>
> struct Filter
> {
> System sys;
> SeverityLevel sev;
>
> bool operator()(???)
> {
> // pseudo-code, since I don't know how to write this
> return Attributes["System"] == sys&& Attributes["SeverityLevel"]>=
> sev;
> }
> };
Well, if you want to develop a filter from ground, here you go:
struct Filter
{
typedef bool result_type;
System m_sys;
SeverityLevel m_sev;
result_type operator() (attribute_values_view const& attrs) const
{
shared_ptr< logging::attribute > attr = attrs["System"];
if (attr)
{
optional< System > sys = attr->get< System >();
if (!sys)
throw runtime_error("The System attribute has invalid type");
if (sys.get() != m_sys)
return false;
}
else
throw runtime_error("The System attribute not found");
attr = attrs["Severity"];
if (attr)
{
optional< SeverityLevel > sev = attr->get< SeverityLevel >();
if (!sev)
throw runtime_error(
"The Severity attribute has invalid type");
if (sev.get() != m_sev)
return false;
}
else
throw runtime_error("The Severity attribute not found");
return true;
}
};
But honestly, it would be much simpler if you used the tools provided by
the library.