У меня есть настройки журнала, в которых у меня есть 2 типа сообщений журнала:
- 1, основанный исключительно на уровне серьезности
- 1, основанный исключительно на атрибуте пользовательского тега
Эти атрибуты определены следующим образом:
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", trivial::severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
Я хочу создать функцию фильтра, которая позволяет добавлять сообщение в мой журнал на основе одного из двух критериев (обратите внимание, что сообщения журнала, основанные на атрибуте пользовательского тега, всегда печатаются с информацией уровня серьезности, основанной на тривиальные уровни серьезности регистратора).
Итак, я хочу иметь фильтр, который разрешает сообщение, основываясь на том, есть ли в сообщении пользовательский тег, и если его нет, в зависимости от серьезности сообщения.
Я попытался установить относительно простой фильтр, который выполняет следующие действия:
sink_->set_filter(
trivial::severity >= severityLevel
|| (expr::has_attr(tag_attr) && tag_attr == "JSON" && logJson_)
);
Но поскольку вполне возможно, что severityLevel может быть либо Debug, Info, Warning, Error или Fatal, если уровень настроен как Debug или Info, атрибут пользовательского тега игнорируется фильтром.
Я пробовал использовать лямбду с ++ 11, как показано ниже:
sink_->set_filter([this, severityLevel](const auto& attr_set) {
if (<condition for custom tag first>) {
return true;
} else if (<condition for severity level second>) {
return true;
} else {
return false;
}
});
Но тогда у меня нет идеи, как на самом деле проверить мои условия. Я пробовал следующее:
if (attr_set["Tag"].extract<std::string>() == "JSON" && logJson_) {
return true;
} else if (attr_set["Severity"].extract<trivial::severity_level>() >= severityLevel) {
return true;
} else {
return false;
}
Но компилятор выдает несколько ошибок по этому поводу:
Core/Source/Log/Logger.cpp: In lambda function:
Core/Source/Log/Logger.cpp:127:48: error: expected primary-expression before '>' token
if (attr_set["Tag"].extract<std::string>() == "JSON" && logJson_) {
^
Core/Source/Log/Logger.cpp:127:50: error: expected primary-expression before ')' token
if (attr_set["Tag"].extract<std::string>() == "JSON" && logJson_) {
^
Core/Source/Log/Logger.cpp:129:72: error: expected primary-expression before '>' token
} else if (attr_set["Severity"].extract<trivial::severity_level>() >= severityLevel) {
^
Core/Source/Log/Logger.cpp:129:74: error: expected primary-expression before ')' token
} else if (attr_set["Severity"].extract<trivial::severity_level>() >= severityLevel) {
^
Core/Source/Log/Logger.cpp: In lambda function:
Core/Source/Log/Logger.cpp:134:5: error: control reaches end of non-void function [-Werror=return-type]
});
^
cc1plus: all warnings being treated as errors
scons: *** [obj/release/Core/Source/Log/Logger.os] Error 1
====5 errors, 0 warnings====
Я сам изучал документацию буст-журнала об извлечении атрибутов, но не могу найти нужную информацию.
EDIT:
Для потомков я добавлю, как я решил свою проблему (благодаря ответу Андрея):
sink_->set_filter([this, severityLevel](const auto& attr_set) {
if (attr_set[tag_attr] == "JSON") {
return logJson_;
} else if (attr_set[severity] >= severityLevel) {
return true;
} else {
return false;
}
});