C++ 如何在boostlog2.0中设置std::ios_基本标志,如std::left?
我有一个广泛使用boostlog2.0的应用程序。现在,我想为该应用程序设置一些默认标志,如C++ 如何在boostlog2.0中设置std::ios_基本标志,如std::left?,c++,logging,boost,boost-log,C++,Logging,Boost,Boost Log,我有一个广泛使用boostlog2.0的应用程序。现在,我想为该应用程序设置一些默认标志,如std::setprecision(std::numeric_limits::digits10+1)、std::scientific和std::left。但是我该怎么做呢?一种方法是在我的主函数的最开始创建一个记录器,并创建一个虚拟日志消息。这将永久设置所需的标志。但是没有更好的方法来做到这一点吗 编辑回复:“OP应显示实际代码。” 我有一个全局日志单例,名为L: class L{ public: e
std::setprecision(std::numeric_limits::digits10+1)
、std::scientific
和std::left
。但是我该怎么做呢?一种方法是在我的主函数的最开始创建一个记录器,并创建一个虚拟日志消息。这将永久设置所需的标志。但是没有更好的方法来做到这一点吗
编辑回复:“OP应显示实际代码。”
我有一个全局日志单例,名为L:
class L{
public:
enum severity_level
{
dddebug,
ddebug,
debug,
control,
iiinfo,
iinfo,
info,
result,
warning,
error,
critical
};
typedef boost::log::sources::severity_channel_logger<
severity_level, // the type of the severity level
std::string // the type of the channel name
> logger_t;
typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_ostream_backend > text_sink;
boost::shared_ptr< text_sink > sink_;
static L& get();
static boost::shared_ptr<text_sink> sink();
static double t0();
static double tElapsed();
private:
L();
double t0_p;
static std::string tElapsedFormat();
L(const L&) = delete;
void operator=(const L&) = delete;
};
我目前解决这个问题的方法是在程序的开头放一条日志语句
int main(){
L::logger_t logger(boost::log::keywords::channel = "init");
BOOST_LOG_SEV(logger, L::critical) << "setting up logger" << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
//do stuff
}
intmain(){
L::logger\u t logger(boost::log::keywords::channel=“init”);
BOOST_LOG_SEV(logger,L::critical)我不相信您当前的方法在所有情况下都能工作,特别是如果您的代码是线程化的。当您说单个logged format标志可以修复多个logger时,我感到紧张,所以我查看了代码(record_ostream.hpp和record_ostream.cpp)
Boost Log使用提供流格式化程序给具有辅助结构的记录器stream\u provider
。stream\u provider
的实现使用线程本地存储(当支持线程时)为每个线程使用一个单独的ostream
实例池。在一个池中,会根据需要创建ostream
实例-如果一次只需要一个格式化程序,则只会创建一个。因此,如果从单个线程登录,并且在记录其他东西时记录一些东西。
线程化失败的原因应该非常明显。下面是一个简单的示例,说明了线程化失败的原因:
静态双f(双x){
BOOST_LOG(my_logger::get())@rhashimoto很好地说明了当前解决方案将如何因多线程/并发日志操作而崩溃。我觉得最好的解决方案是定义自己的日志宏来替换包含流修饰符的BOOST_logger_SEV
,如下所示:
#define LOG_SCIENTIFIC(logger, sev) (BOOST_LOG_SEV(logger, sev) << std::scientific)
#define BOOST_LOG_SEV(logger, lvl) (BOOST_LOG_STREAM_SEV(logger, lvl) << std::scientific)
由于BOOST\u LOG\u STREAM\u SEV
仍然是公共BOOST API的一部分,您应该能够安全地重新定义BOOST\u LOG\u SEV
如下:
#define LOG_SCIENTIFIC(logger, sev) (BOOST_LOG_SEV(logger, sev) << std::scientific)
#define BOOST_LOG_SEV(logger, lvl) (BOOST_LOG_STREAM_SEV(logger, lvl) << std::scientific)
#定义BOOST_LOG_SEV(记录器,lvl)(BOOST_LOG_STREAM_SEV(记录器,lvl)日志记录很少需要格式化。如果需要格式化,您可以使用格式化,只需记录预格式化的字符串。@JoachimPileborg对于我的工作来说,必须使用'std::scientific'。任何未启用它的双日志记录都不会给我提供任何信息,因此我想将其设置为全局标准。您的日志记录是什么g现在看起来怎么样?你有一个全局可访问的记录器吗?你在使用BOOST_LOG宏吗?@WilliamKunkel我在每个类中都有一个静态记录器成员来设置通道名称的默认值。要记录日志,我使用BOOST_LOG_SEV。问题是执行BOOST_LOG_SEV(…)窥视。BOOST LOG有很多选项来实现这一点(我用了一些方法),但这个问题确实缺少任何细节来决定什么是合适的。这些数字将如何记录?它们是属性吗?它们只是使用流式操作流式处理吗?使用了哪些记录器实例?换句话说,OP应该显示实际代码。/cc@JoachimPileborg
//! An equivalent to BOOST_LOG_STREAM_SEV(logger, lvl)
#define BOOST_LOG_SEV(logger, lvl) BOOST_LOG_STREAM_SEV(logger, lvl)
#define BOOST_LOG_SEV(logger, lvl) (BOOST_LOG_STREAM_SEV(logger, lvl) << std::scientific)