I'm using a sink to log information and a file with information on the different levels I want for each tag I created like so:
sink->set_filter(logging::trivial::severity >= logging::trivial::warning && expr::attr<std::string>("Tag") == tag);
[...]
sink->set_filter(logging::trivial::severity >= logging::trivial::warning && expr::attr<std::string>("Tag") == tag1);
with both tag and tag1 different tags
I also tried to apply the documentation of boost::phoenix to my problem but I can't figure out how to implement it.
Right now, I have this code, but it just overrides the filter each time I get into a leaf.
void setSinks()
{
logging::core::get()->add_global_attribute("Tag", attrs::mutable_constant<std::string>(""));
std::string path = "..../log_config.json";
[def of sink...]
pt::ptree root;
pt::read_json(path, root);
std::function<void(pt::ptree, std::string)> parse_tree;
auto setFilter = [](std::string tag, std::string logLevel) {
logging::trivial::severity_level level;
if (logLevel == "TRACE") level = logging::trivial::trace;
else if (logLevel == "DEBUG") level = logging::trivial::debug;
else if (logLevel == "INFO") level = logging::trivial::info;
else if (logLevel == "WARNING") level = logging::trivial::warning;
else if (logLevel == "ERROR") level = logging::trivial::error;
else if (logLevel == "FATAL") level = logging::trivial::fatal;
else level = logging::trivial::debug;
return logging::trivial::severity >= level && expr::attr<std::string>("Tag") == tag;
};
parse_tree = [&sink, &setFilter, &parse_tree](pt::ptree tree, std::string tag)
{
for (const auto& v : tree)
{
std::string name = v.first;
pt::ptree value = v.second;
if (value.empty())
{
sink->set_filter(setFilter(tag + "." + name, value.data()));
}
else
{
parse_tree(value, (tag.empty() ? name : tag + "." + name));
}
}
};
parse_tree(root, "");
}
If your list of tags is known and fixed at compile time, you can compose a filter using template expressions like this:
Here,
tag1,tag2,severity1andseverity2may be constants or dynamic values, e.g. obtained from a file.If the list of tags is more dynamic, you could use
channel_severity_filter. It is used to map severity level thresholds to different channels, and in your case your "Tag" attribute plays the role of a channel name.You may also combine this filter with other template expressions, as shown in the docs.
Lastly, you can implement whatever filtering logic you want by writing your own filtering function.
You can also do away with Boost.Phoenix and implement attribute value extraction yourself.