设计目标:
1、每个Logging source对应一个目录,可以设置日志文件数,日志大小,目录名,文件名等
2、所有logging source日志目录都在一个根目录下。
3、可以动态创建和删除logging source
4、打印出日期时间和日志严重等级
示例代码:
#include <libs/Core/LogMananger.h>int main(){LogManager::instance().setRootPath("logs");LogManager::instance().addLogger("network", "network", 1024*100, 10);LogManager::instance().addLogger("db", "db", 1024*100, 10);for(int i = 0; i < 10000; i++){LOG(network, info) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(network, trace) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(network, warning) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(network, fatal) << "hello world ";LOG(network, debug) << "hello world";LOG(db, info) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(db, trace) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(db, warning) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(db, fatal) << "hello world";LOG(db, debug) << "hello world";}return 0;
}
生成的日志目录结构:
日志格式:
LogManager.h
#pragma once
#include <boost/log/trivial.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/basic_logger.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/core.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/sinks.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/attributes/constant.hpp>
#include <boost/log/exceptions.hpp>
#include <boost/log/keywords/format.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/expressions/formatters/date_time.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>#include <memory>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <mutex>
using namespace std;
namespace sources = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace expressions = boost::log::expressions;
namespace trivial = boost::log::trivial;
namespace keywords = boost::log::keywords;
namespace attributes = boost::log::attributes;class LogManager
{struct LoggerInfo{string m_strName;string m_strPath;int m_nMaxSize;int m_nMaxCount;boost::shared_ptr<sources::severity_logger_mt<trivial::severity_level>> m_pLogger;boost::shared_ptr<sinks::synchronous_sink<sinks::text_file_backend>> m_pSink;};
public:~LogManager();static LogManager& instance();void setRootPath(const string& strRootPath = "");void addLogger(const string& strName, const string& strPath, int nMaxSize, int nMaxCount);void removeLogger(const string& strName);boost::log::sources::severity_logger_mt<trivial::severity_level>& getLogger(const string& strName);
private:LogManager();
private:string m_strRootPath;map<string, LoggerInfo> m_mapLogger;mutex m_oLock;
};#define LOG(name, level) BOOST_LOG_SEV(LogManager::instance().getLogger(#name), boost::log::trivial::severity_level::level)
LogManager.cpp
#include "LogMananger.h"LogManager::LogManager()
{}LogManager::~LogManager()
{}LogManager& LogManager::instance()
{static LogManager t;return t;
}void LogManager::setRootPath(const string& strRootPath)
{m_strRootPath = strRootPath;
}void LogManager::addLogger(const string& strName, const string& strPath, int nMaxSize, int nMaxCount)
{lock_guard<mutex> lk(m_oLock);if(m_mapLogger.contains(strName))return;m_mapLogger[strName] = LoggerInfo();m_mapLogger[strName].m_strName = strName;m_mapLogger[strName].m_strPath = strPath;m_mapLogger[strName].m_nMaxSize = nMaxSize;m_mapLogger[strName].m_nMaxCount = nMaxCount;m_mapLogger[strName].m_pLogger = boost::make_shared<sources::severity_logger_mt<trivial::severity_level>>();m_mapLogger[strName].m_pLogger->add_attribute("LoggerName", attributes::constant<string>(strName));m_mapLogger[strName].m_pLogger->add_attribute("DateTime", attributes::local_clock());boost::shared_ptr<sinks::text_file_backend> pTxtFileBackend = boost::make_shared<sinks::text_file_backend>( keywords::file_name = m_strRootPath + "/" + strPath + "/" + strName + ".log", //是日志文件大小没达到最大值时,日志写的文件keywords::target_file_name = strName + "_%2N.log", //当日志文件达到最大值时,日志文件名会被改写,这里的%2N,表示用两位数字表示keywords::rotation_size = nMaxSize, //单个日志文件最大值,这里是5Mkeywords::open_mode = std::ios_base::out | std::ios_base::app, //添加模式keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0)); //每天12点会重新生成一个日志文件,不管日志文件是否到了最大值m_mapLogger[strName].m_pSink = boost::make_shared<sinks::synchronous_sink<sinks::text_file_backend>>(pTxtFileBackend);m_mapLogger[strName].m_pSink->locked_backend()->set_file_collector(sinks::file::make_collector(keywords::max_files = nMaxCount, //最多N个日志文件keywords::max_size = nMaxSize*(1+nMaxCount), //正目录最大占用多少磁盘空间keywords::target = m_strRootPath + "/" + strPath //日志保存的目录,前面target_file_name所在的目录));m_mapLogger[strName].m_pSink->locked_backend()->auto_flush(true);m_mapLogger[strName].m_pSink->locked_backend()->scan_for_files();m_mapLogger[strName].m_pSink->set_formatter(expressions::stream<< expressions::if_(expressions::has_attr<boost::posix_time::ptime>("DateTime"))[expressions::stream << "[" << expressions::format_date_time< boost::posix_time::ptime >("DateTime", "%Y-%m-%d %H:%M:%S.%f") << "] "]<< "[" << trivial::severity << "] "<< expressions::smessage);m_mapLogger[strName].m_pSink->set_filter(expressions::has_attr("LoggerName") && expressions::attr<string>("LoggerName") == strName);boost::log::core::get()->add_sink(m_mapLogger[strName].m_pSink);
}void LogManager::removeLogger(const string& strName)
{lock_guard<mutex> lk(m_oLock);if(m_mapLogger.contains(strName))boost::log::core::get()->remove_sink(m_mapLogger[strName].m_pSink);
}sources::severity_logger_mt<trivial::severity_level>& LogManager::getLogger(const string& strName)
{lock_guard<mutex> lk(m_oLock);return *m_mapLogger[strName].m_pLogger;
}