boost-log日志组件

boost-log

常用简写

1
2
3
4
5
6
namespace logging  = boost::log;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace sinks = boost::log::sinks;
namespace attrs = boost::log::attributes;
namespace keywords = boost::log::keywords;

boost-log的结构图


boost::log 的设计主要有日志器(Logger)、日志核心(Logging core)、Sink 前后端(frontend, backend)组成.日志文本以及日志环境由日志器(Logger)负责搜集,日志核心负责处理日志数据(例如全局过滤、将日志记录传递给 Sink ),Sink前端分为同步、异步以及不考虑线程同步问题的版本,它们负责将日志记录传递给 Sink 后端处理.Sink后端负责把日志记录格式化并输出到不同的介质中(例如日志文件、报警以及统计源中).

Logging core的获取

1
2
#include <boost/log/core.hpp>
boost::shared_ptr<logging::core> core = logging::core::get();

sink对象创建

需要先创建一个backend对象,然后在创建sink对象的时候,将backend对象传递给它

1
2
3
4
5
6
7
8
typedef sinks::synchronous_sink<sinks::text_file_backend> TextSink;
// init sink
boost::shared_ptr<sinks::text_file_backend> backend = boost::make_shared<sinks::text_file_backend>(
keywords::file_name = "sign_%Y-%m-%d_%H-%M-%S.%N.log",
keywords::rotation_size = 10 * 1024 * 1024,
keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
keywords::min_free_space = 30 * 1024 * 1024);
boost::shared_ptr<TextSink> sink(new TextSink(backend));

backend创建

指定frontend类型

backend的类型需要一个frontend类型作为其模版类,当创建一个backend对象时,已经确定了frontend.
frontend模版可以使用synchronous_sink类或者asynchronous_sink类,后者不会阻塞调用程序,会创建额外线程处理log,不过会慢点,内存消耗大点.一般推荐使用后者.

用keywords构造参数

boost/log/keywords目录下hpp文件

1
2
3
4
[CaseZheng@VM_187_252_centos keywords]$ ls
auto_flush.hpp channel.hpp empty_marker.hpp file_name.hpp ident.hpp iteration.hpp max_files.hpp min_free_space.hpp order.hpp permissions.hpp scan_method.hpp target.hpp
block_size.hpp delimiter.hpp enable_final_rotation.hpp filter.hpp incomplete_marker.hpp log_name.hpp max_size.hpp name.hpp ordering_window.hpp registration.hpp severity.hpp time_based_rotation.hpp
capacity.hpp depth.hpp facility.hpp format.hpp ip_version.hpp log_source.hpp message_file.hpp open_mode.hpp overflow_policy.hpp rotation_size.hpp start_thread.hpp use_impl.hpp

keywords是boost库的基本概念,设计到一个宏BOOST_PARAMETER_KEYWORD,定义在boost/parameter/keywords.hpp文件中, 主要作用就是在指定的namespace中创建一个singleton的对象。

1
keywords::file_name = "sign_%Y-%m-%d_%H-%M-%S.%N.log",

上述代码:给keywords namespace下的singleton对象file_name赋值.
text_file_backend的构造函数语法上支持变参,但是语义上只支持有限的keywords

sink指定格式

指定日志格式,在sink中指定

1
2
3
4
5
6
7
sink->set_formatter (
expr::format("[%1%]<%2%>(%3%): %4%")
% expr::format_date_time< boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S")
% expr::attr<sign_severity_level>("Severity")
% expr::attr<attrs::current_thread_id::value_type>("ThreadID")
% expr::smessage
);

Boost::Format风格

1
2
3
4
5
6
7
8
logging::formatter fmt = expr::stream
<< std::setw(6) << std::setfill('0') << line_id << std::setfill(' ')
<< ": <" << severity << ">\t"
<< expr::if_(expr::has_attr(tag_attr))
[
expr::stream << "[" << tag_attr << "] "
]
<< expr::smessage;

sink对象安装

1
core->add_sink(sink);

attributes

根据设计,日志记录是由attributes组成的,所以打印内容必须以attribute的方式传给sink对象

1
2
3
4
5
6
7
8
sink->set_formatter (
expr::format("[%1%]<%2%>(%3%)(%4%): %5%")
% expr::attr<unsigned int>("LineID")
% expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
% expr::attr<sign_severity_level>("Severity")
% expr::attr<attrs::current_thread_id::value_type >("ThreadID")
% expr::smessage
);

不要忘记添加commont attributes

1
logging::add_common_attributes();

示例代码

boost log封装示例代码 log.cpp
boost log封装示例代码 log.h