- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个日志设置,其中有两种类型的日志消息:
这些属性定义如下:
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", trivial::severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
我想创建一个过滤器功能,允许根据 2 个标准中的任何一个将消息添加到我的日志中(请注意,基于自定义标签属性的日志消息总是打印严重级别信息,基于琐碎的记录器的严重级别)。
所以我想要一个过滤器,它允许基于消息是否具有自定义标记的消息,如果没有,则基于消息的严重性。
我尝试使用一个相对简单的过滤器来执行以下操作:
sink_->set_filter(
trivial::severity >= severityLevel
|| (expr::has_attr(tag_attr) && tag_attr == "JSON" && logJson_)
);
但由于 severityLevel 可能是 Debug、Info、Warning、Error 或 Fatal,如果级别配置为 Debug 或 Info,自定义标记属性将被过滤器忽略。
我试过使用 c++11 lambda,如下所示:
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====
我一直在搜索关于自己提取属性的 boost 日志文档,但找不到我需要的信息。
编辑:
为了后代,我将添加我是如何解决我的问题的(感谢 Andrey 给出的答案):
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;
}
});
最佳答案
过滤器可以用多种方式编写,我将演示几种替代方法。
首先,使用表达式模板你可以这样写:
sink_->set_filter(
(expr::has_attr(tag_attr) && tag_attr == "JSON" && logJson_) ||
trivial::severity >= severityLevel
);
按照C++的正常短路规则,首先会测试标签属性,如果条件成功,则不会测试严重性。如果标签不存在或不是 JSON 或 logJson_
不正确,则测试严重性级别。
请注意,上面的过滤器将在构建时保存其参数的副本(包括 logJson_
和 severityLevel
),因此如果您更改 logJson_
稍后过滤器将继续使用旧值。这与您后来尝试使用 C++14 lambda 的一个重要区别,后者访问 logJson_
。通过捕获的 this
指针。如果你真的想保存对你的成员的引用 logJson_
在过滤器中,您可以使用 phoenix::ref
:
sink_->set_filter(
(expr::has_attr(tag_attr) && tag_attr == "JSON" && boost::phoenix::ref(logJson_)) ||
trivial::severity >= severityLevel
);
但是,你应该记住过滤器可以在多个线程中并发调用,所以访问logJson_
不 protected 。如果要更新 logJson_
,则必须实现自己的线程同步在运行时。
除非多线程问题,否则您对 lambda 的第二次尝试几乎是正确的。编译器提示是因为 lambda 函数是一个模板,而 attr_set["Tag"]
的结果表达式取决于模板参数之一(即 attr_set
的类型)。在这种情况下,程序员必须限定以下 extract<std::string>()
expression 是模板实例化而不是比较序列。这是通过添加 template
来完成的。关键词:
if (attr_set["Tag"].template extract<std::string>() == "JSON" && logJson_) {
return true;
} else if (attr_set["Severity"].template extract<trivial::severity_level>() >= severityLevel) {
return true;
} else {
return false;
}
请注意,您可以使用独立函数来达到相同的效果,这不需要模板限定:
if (boost::log::extract<std::string>("Tag", attr_set) == "JSON" && logJson_) {
return true;
} else if (boost::log::extract<trivial::severity_level>("Severity", attr_set) >= severityLevel) {
return true;
} else {
return false;
}
最后,提取属性值的首选方法是利用您之前声明的属性关键字。这不仅可以避免模板限定怪癖,还可以消除大量代码重复。
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", trivial::severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
if (attr_set[tag_attr] == "JSON" && logJson_) {
return true;
} else if (attr_set[severity] >= severityLevel) {
return true;
} else {
return false;
}
在这种情况下,属性值名称和类型是从关键字声明中推断出来的。 this 末尾记录了属性关键字的这种使用部分。
关于filtering - 使用自定义属性和严重级别为提升日志接收器设置自定义过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52206677/
目前我正在调试我们的应用程序一个看似随机的错误。我将尝试提供尽可能多的细节。基本上过了一会儿,我们服务器上的应用程序的一个应用程序池停止了。我必须启动它,或者有时,重新启动 Coldfusion 或更
在寻找其他东西时,完全出于巧合,我偶然发现了一些关于案例类继承是多么邪恶的评论。有一个叫做 ProductN 的东西,可怜虫和国王, Sprite 和巫师,以及案例类继承如何丢失某种非常理想的属性。那
我正在从服务器下载媒体内容,并且应用程序在一定时间后崩溃,并给出以下错误: 收到内存压力通知(严重) 当我在 didReceiveMemoryWarning 函数中收到警告时删除了所有对象,但没有运气
为什么我会遇到这个错误 我开发了 Jax-Rs Web 服务 Jersey、Maven、Hibernate 和 Spring。如何解决该错误? Aug 03, 2015 2:23:17 PM com.
我是 Perl 新手。我收到此错误: CRITICAL : "file does not exist" 当我尝试运行脚本来通过 Nagios 监视 httpd 错误日志时。 #!/bin/sh # C
我最近一直在努力在 Kivy 中创建一个填充的 Circle,当窗口的大小调整为不同的宽度或高度时,它仍然是一个圆。我在这里看了问题: Centering an object in Kivy 但是当我
我想用实验编程语言实现的主要目的之一是:发生错误(语法,名称,类型等)时,无论程序有多严重或破坏性如何,都可以保持程序运行。 我知道这可能非常糟糕,但是我只想要一些不会在每个错误中都消失的东西-,我发
我使用 NetBeans 来制作我的 Java 项目。在我的数据库表或 DTO 中,它们都有一个名为“paymentDate ”的列。我不明白为什么它会发送此错误。奇怪的是,当我将“PAYMENTDA
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我正在使用Grails 1.3.4,后者使用了Hibernate,并且针对Oracle 11g数据库。我的应用程序启动失败,出现以下错误: 2010-11-04 09:45:34,671 INFO
自从我执行了 pip install google-api-python-client 后,我的 Gunicorn worker 在超时后停止了。 Django==1.5.3 unicorn ==
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Connecting to SQLite Database Fails 我是 Java 初学者 当我想从 SQLit
在我的实体类中,我有以下内容,调用一个返回 sys_refcursor 的 oracle 函数 @Entity @javax.persistence.NamedNativeQuery(
我们在生产环境中遇到了这个问题,但无法追踪。技术:JSP/Servlets,Jetty 服务器版本:jetty-distribution-8.1.15, 以下是异常(exception)情况,我们在
我有一个基于网络的应用程序,每三秒我连接到一个数据库并从 GPS 设备查询数据。 不幸的是,当应用程序工作超过几个小时时我无缘无故地得到了异常:“严重:没有找到适合jdbc的驱动程序......”。应
之前我的 tomcat 服务器运行良好。 但突然出现以下错误。 请帮忙解决这个问题 SEVERE: A child container failed during start java.util.co
请不要标记为重复,因为其他解决方案还没有帮助! 我在尝试运行本教程时在浏览器中收到 404: http://www.vogella.com/articles/REST/article.html 实际上
使用 Spring Tool Suite 3.6.3,我将以下内容添加到 Maven Web 项目的 POM.XML 中。 com.MyCompany.sei MyCompany-a
我在 tomcat 上部署了 RESTful Web 服务'该 Web 服务在同一域场景的客户端/服务器中工作正常'但我需要使 Web 服务可从跨域使用'为此我使用了 CORS 过滤器. 我在 myP
我第一次尝试使用 ServletContextListener 在每次部署应用程序时执行特定函数。为此,我采用了一个简单的 java 类文件并在其上实现了 ServletContextListener
我是一名优秀的程序员,十分优秀!