如何为std::ostream实现带短路优化的日志Verbosity过滤器?
日志Verbosity过滤的优雅实现问题
以下是一种暴力但不够优雅的实现方式(最终可通过宏来实现):
void myFunction(std::ostream& _log) { int threshold = 100; ... if (threshold >= 200) { _log << "Message with level 200 verbosity"; // 不会输出 } if (threshold >= 0) { _log << "Message with level 0 verbosity"; // 会输出 } ... }
注意:当消息因未达到Verbosity阈值被过滤时,开销极低——消息的构造和处理操作会被完全跳过。
我们希望实现更优雅的写法,示例如下:
class MessageFilteringOStream : std::ostream { ... void setMessageThreshold(unsigned int threshold) { _threshold = threshold; } ... } ... void myFunction(MessageFilteringOStream& _log) { _log.setMessageThreshold(100); ... _log << _log.verbosity(200) << "Message with level 200 verbosity"; // 不会输出 _log << _log.verbosity( 0) << "Message with level 0 verbosity"; // 会输出 ... }
要实现这个方案,需要完成以下步骤,前两步相对简单,第三步该如何处理?
- 继承
std::ostream,添加threshold和message_verbosity成员变量。 - 添加
verbosity()方法,将当前消息的Verbosity值存入message_verbosity(可参考std::setw()的实现思路)。 - 当
threshold < message_verbosity时拦截输入并过滤所有内容,或许可以通过重载operator<<实现?
但如果无法“短路”跳过那些会被过滤的消息的构造过程,这个方案就得不偿失了,我不清楚该怎么实现这一点?
编辑补充:
感谢大家的建议。当前代码库中多处传递std::ostream引用,我希望仅在顶层修改Verbosity设置,无需修改所有消息生成的地方,但这似乎并不容易。我可以在puts()层面拦截,但此时消息已构造完成(且数量可能很多),我仍在思考大家的建议。
内容的提问来源于stack exchange,提问作者Lance E.T. Compte
相关产品推荐
相关产品推荐

