第七个工具类:Logger
就是用于输出日志的一个工具类,很简单,就是封装了一下boost库的log
不熟悉boost的log库的同学,可能就需要提前熟悉一下
本工具类,就是默认用exe的文件名比如“Test.exe”加上“_log”,组成一个文件夹名称“Test.exe_log”,
在Test.exe的同级目录下,创建这个文件夹“Test.exe_log”,所有的log都会输出到这个文件夹(这里就用到了之前的ExePath)
每个log对象,会有一个sinkname,用于将不同的日志输出到不同的文件中
比如,定义两个logger对象:
Logger g_SystemLog("System");
Logger g_LogicLog("Logic");
则向g_SystemLog输出的日志信息,将会输出到Test.exe_log/System_年月日.log的文件中
g_LogicLog输出的日志信息,将会输出到Test.exe_log/Logic_年月日.log的文件中
日志文件最后的那个后缀“_年月日”,会按照系统时间,每天换一次,即每到每天的00:00:00
则会以新的日期自动生成一个新文件
具体的日志输出用宏:
比如 :LOG_INFO(g_SystemLog) << "你要输出的日志";
#include "Logger.h"
using namespace common::tool;
Logger g_SystemLog("System");
int main(int argc, char* argv[])
{
LOG_INFO(g_SystemLog) << "hello world";
unsigned int a = 123;
std::string b = "345";
LOG_INFO(g_SystemLog) << "a = " << a << ", b = " << b;
return 0;
}
输出文件:
最后完整代码:
Logger.h
#ifndef __Logger_h__
#define __Logger_h__
#include <string>
#include <boost/log/trivial.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#define LOG_DEBUG(logObj) \
BOOST_LOG_SEV(logObj.GetLog(), boost::log::trivial::debug) << "file:" << __FILE__ << "(" << __LINE__ << "):" << __FUNCTION__ << ":"
#define LOG_INFO(logObj) \
BOOST_LOG_SEV(logObj.GetLog(), boost::log::trivial::info) << "file:" << __FILE__ << "(" << __LINE__ << "):" << __FUNCTION__ << ":"
#define LOG_ERROR(logObj) \
BOOST_LOG_SEV(logObj.GetLog(), boost::log::trivial::error) << "file:" << __FILE__ << "(" << __LINE__ << "):" << __FUNCTION__ << ":"
#define LOG_WARNING(logObj) \
BOOST_LOG_SEV(logObj.GetLog(), boost::log::trivial::warning) << "file:" << __FILE__ << "(" << __LINE__ << "):" << __FUNCTION__ << ":"
namespace common{
namespace tool{
class Logger
{
public:
Logger(const std::string& sink);
~Logger();
boost::log::sources::severity_channel_logger<boost::log::trivial::severity_level, std::string>& GetLog()
{
return m_log;
}
private:
void Init(const std::string& dir);
boost::log::sources::severity_channel_logger<boost::log::trivial::severity_level, std::string> m_log;
std::string m_SinkName;
};
}
}
#endif
Logger.cpp
#include "Logger.h"
#include <boost/filesystem.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/detail/format.hpp>
#include <boost/log/detail/thread_id.hpp>
#include "ExePath.h"
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>)
namespace common{
namespace tool{
Logger::Logger(const std::string& sink) : m_SinkName(sink), m_log(boost::log::keywords::channel = sink)
{
std::string fullName = GetExePathAndName();
fullName += "_log";
Init(fullName);
}
Logger::~Logger()
{
}
void Logger::Init(const std::string& dir)
{
if (!boost::filesystem::exists(dir))
{
boost::filesystem::create_directories(dir);
}
boost::shared_ptr<boost::log::sinks::text_file_backend> backend = boost::make_shared<boost::log::sinks::text_file_backend>(
boost::log::keywords::open_mode = std::ios::app,
boost::log::keywords::file_name = dir + "/" + m_SinkName + "_%Y%m%d.log",
boost::log::keywords::rotation_size = 10 * 1024 * 1024,
boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0));
typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend> TextSink;
boost::shared_ptr<TextSink> sink(new TextSink(backend));
sink->set_formatter(
boost::log::expressions::format("[%1% %2% %3%]:%4%")
% boost::log::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
% boost::log::expressions::attr<boost::log::aux::thread::id>("ThreadID")
% boost::log::expressions::attr<boost::log::trivial::severity_level>("Severity")
% boost::log::expressions::smessage);
sink->set_filter(boost::log::expressions::attr<std::string>("Channel") == m_SinkName);
sink->locked_backend()->auto_flush(true);
boost::log::core::get()->add_sink(sink);
boost::log::add_common_attributes();
}
}
}