1. 程式人生 > >boost log -- 使用心得和碰到的那些坑(二)

boost log -- 使用心得和碰到的那些坑(二)

前一篇文章boost log – 使用心得和碰到的那些坑(一) 寫了如何使用boost;;log, 這篇文章主要寫寫怎樣用boost;;log構建一個工程,目的就是讓使用者使用時忘掉log細節。

專案依賴

boost c++11 cmake

設計

為了以後擴充套件方便,將log設計成介面。 介面提供基本的log功能:

class logger_iface
{
  public:
  public:
	logger_iface(void)= default;
	virtual ~logger_iface(void) = default;
	logger_iface(const logger_iface &) = default;
	logger_iface &operator=(const logger_iface &) = default;

  public:
	virtual void init() = 0;
	virtual void set_log_level(log_level level) = 0;
	virtual void debug_log(const std::string &msg, const std::string &file, std::size_t line) = 0;
	virtual void info_log(const std::string &msg, const std::string &file, std::size_t line) = 0;
	virtual void warn_log(const std::string &msg, const std::string &file, std::size_t line) = 0;
	virtual void error_log(const std::string &msg, const std::string &file, std::size_t line) = 0;
	virtual void critical_log(const std::string &msg, const std::string &file, std::size_t line) = 0;
};

boost logger 繼承這個類。
前文已經提到了,boost logger 需要一個log core 一個sink,同時使用async backend。所以boost logger實現介面的同時加入這兩個成員變數。

	boost::shared_ptr<sink_t> _sink;
	boost::log::sources::severity_logger_mt<log_level> lg;

利用前文所寫的實現這幾個函式,需要注意的是 log level其實就是設定boost;;log的 filter

void boost_logger::set_log_level(log_level level)
{
	m_level = level;
	if (_sink)
	{
		_sink->set_filter(expr::attr<log_level>("Severity") >= m_level);
	}
}

現在class功能都已經實現,如何使用呢?我們需要的就是__LOG(level, msg)這樣簡單的API。這需要有個全域性的例項。
還有一個要考慮的是, boost;;logger沒有提供檔案及檔案行號資訊。
解決這個問題, 我們有個巨集定義:

#define __LOG(level, msg)                              \
                                                       \
	{                                                  \
		tostringstream var;                            \
		var << "[fuction:" << __func__ << "] " << msg; \
		level(var.str(), __FILE__, __LINE__);          \
	}
#else
#define __LOG(level, msg)
#endif /* __LOGGING_ENABLED */

其實level是一個函式,msg提供了像std;;cout一樣的用法。

下面我們看看level是怎麼實現的:

void debug(const std::string &msg, const std::string &file, std::size_t line)
{
	if (active_logger)
		active_logger->debug_log(msg, file, line);
}

active_logger是一個全域性的instance。

std::unique_ptr<logger_iface> active_logger(new boost_logger(log_level::error_level)); //nullptr;