使用Boost日志进行日志记录(杜) - 我成功的初始化:
BOOST_LOG_GLOBAL_LOGGER_INIT(logger, logger_t) {
logger_t lg;
logging::add_common_attributes();
boost::shared_ptr< file_sink > sink(new file_sink(
boost::log::keywords::file_name = "appLog_%N.log",
boost::log::keywords::rotation_size = 2 * 1024 * 1024,
boost::log::keywords::max_size = 10 * 1024 * 1024,
boost::log::keywords::scan_method =
boost::log::sinks::file::scan_method::scan_matching,
boost::log::keywords::open_mode = std::ios_base::app,
boost::log::keywords::auto_flush = true
));
sink->set_formatter(
expr::stream
<< expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%dT%H:%M:%S.%fz")
<< ": [" << logging::trivial::severity
<< "]\t" << expr::smessage
);
sink->locked_backend()->set_file_collector(boost::log::sinks::file::make_collector(
boost::log::keywords::target = "", /*< the target directory >*/
boost::log::keywords::max_size = 10 * 1024 * 1024, /*< maximum total size of the stored files, in bytes >*/
boost::log::keywords::min_free_space = 1 * 1024 * 1024, /*< minimum free space on the drive, in bytes >*/
boost::log::keywords::max_files = 10 /*< maximum number of stored files >*/
));
sink->locked_backend()->scan_for_files(boost::log::sinks::file::scan_method::scan_matching, true);
logging::core::get()->add_sink(sink);
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::info
);
return lg;
}
然而,读取和处理所述应用程序的配置文件,其包括值规定rotation_size和MAX_SIZE用于记录,我有困难除去所有片,具有用于rotation_size指定值创建一个新的接收器之前,简单地max_size个后增加了一个散热器上的顶(被记录,这导致每个消息中两次),将其全局初始化现有水槽。
更新日志的大小的功能如下:
void setLoggerSizes(int rotationSize, int maxSize)
{
//INFO << "";
logging::core::get()->remove_all_sinks();
logging::add_common_attributes();
boost::shared_ptr< file_sink > sink(new file_sink(
boost::log::keywords::file_name = "appLog_%N.log",
boost::log::keywords::rotation_size = rotationSize * 1024 * 1024,
boost::log::keywords::max_size = maxSize * 1024 * 1024,
boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching,
boost::log::keywords::open_mode = std::ios_base::app,
boost::log::keywords::auto_flush = true
));
sink->set_formatter(
expr::stream
<< expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%dT%H:%M:%S.%fz")
<< ": [" << logging::trivial::severity
<< "]\t" << expr::smessage
);
sink->locked_backend()->set_file_collector(
boost::log::sinks::file::make_collector(
boost::log::keywords::target = "",
boost::log::keywords::max_size = maxSize * 1024 * 1024,
boost::log::keywords::min_free_space = 1 * 1024 * 1024
)
);
sink->locked_backend()->scan_for_files();
logging::core::get()->add_sink(sink);
}
但是,如果我在函数的开头中添加INFO << "";
,这似乎强制删除所有汇,并用正确的文件大小增加水槽时,结果在一个水池(和消息的结果只有一个副本是传递给日志)。
因此,我的问题是:
INFO << "";
?它没有任何逻辑意义,为什么加这条线将真正强制拆除被称为下一行所有汇 - 并因此导致被记录的消息的一个副本。然而,不包括INFO线,它像logging::core::get()->remove_all_sinks();
呼叫被忽略,并且其中加入与正确的文件大小的接收器是在初始化水槽的顶部加入,并在每一个消息的两个副本的结果被记录。作为参考,这是Logger.h文件:
#pragma once
#include <boost/log/expressions.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup.hpp>
#define FATAL BOOST_LOG_SEV(logger::get(), boost::log::trivial::fatal)
#define WARNING BOOST_LOG_SEV(logger::get(), boost::log::trivial::warning)
#define INFO BOOST_LOG_SEV(logger::get(), boost::log::trivial::info)
#define DEBUG BOOST_LOG_SEV(logger::get(), boost::log::trivial::debug)
#define TRACE BOOST_LOG_SEV(logger::get(), boost::log::trivial::trace)
typedef boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger_t;
typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend > file_sink;
BOOST_LOG_GLOBAL_LOGGER(logger, logger_t)
void setLoggerSizes(int rotationSize, int maxSize);
你看到的问题是最有可能的,因为在你的程序中的日志语句的执行顺序的。
在BOOST_LOG_GLOBAL_LOGGER_INIT
和类似BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT
宏的身体的时候,全球记录是由程序的第一次(见here)要求执行一次。所以,既然你从INFO
宏内要求记录器,是你叫remove_all_sinks
进一步初始化日志库之前执行的身体。当你评论说行,即初始化被推迟到你的第一个执行的日志记录语句,该语句,想必,setLoggerSizes
返回后发生的。因此,remove_all_sinks
有没有影响,因为没有汇在该电话的时点将其删除。
该_INIT
宏真的打算初始化记录器,而不是整个记录库(即水槽,过滤器和什么不可以)。您可以从初始化这些宏库,但是,正如你已经发现,这样做的有用性是相当有限(基本上如预期一样,除非你有一个单一的全球记录,这也是你唯一的记录它可能会无法正常工作在你的整个应用程序中使用,而且你不需要一旦它被初始化为更新日志配置)。要做到这一点,正确的方法是在你将在你的main
早期调用一些时间的函数分别初始化日志库,并使用_INIT
宏只初始化记录器。