boost日志库

自己很久前整理开发了一个boost线程安全日志库,使用了很久,可放心使用;使用方法如下:

1、代码中添加boost_log.h和boost_log.cpp文件;

2、在程序的入口添加

#ifdef _DEBUG
        BoostLog::Init_Release("log", "videolog", debug);
#else
        BoostLog::Init_Release("log", "videolog", info);
#endif // _DEBUG

如果需要将信息输出到控制台,则将Init_Release换位Init_Debug,第一个参数为日志目录,第二个参数为日志名称,第三个为日志等级;

日志会自动划分每个文件的大小为10M,而且整个目录大小限制为100M;

3、写日志:

根据日志级别,分别调用如下宏即可:

BOOST_TRACE
BOOST_DEBUG
BOOST_INFO
BOOST_WARNING
BOOST_ERROR
BOOST_FATAL
BOOST_CB

如:
        BOOST_ERROR << "open udp port excption :" << "绑定地址失败!";

日志输出格式为:

[2016-11-30 09:41:53.375260]<error>http_client.cpp[31]:open udp port excption :绑定地址失败!

4、退出时,在程序的出口调用:

BoostLog::Uninit()

5、代码如下:

boost_log.h

/*!
* \file   Boostlog.hpp
* \author cgb
*
* 封装boost log模块,多线程(同步)写入日志;
*/

#pragma once
#include <string>
#include <iostream>
#ifdef _WIN32
#include <process.h>
#else
#include <unistd.h>
#endif
#ifdef _VS2013
#include <stdint.h>
#endif // _VS2013
#include "boost/log/trivial.hpp"
#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/console.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 "boost/log/core/core.hpp"
#include "boost/format.hpp"

#define _CSTDIO_
#define _CSTRING_
#define _CWCHAR_

using std::string;

namespace boost_log = boost::log;
namespace boost_sources = boost::log::sources;
namespace boost_keywords = boost::log::keywords;
namespace boost_sinks = boost::log::sinks;
namespace boost_expressions = boost::log::expressions;
namespace boost_attributes = boost::log::attributes;
namespace boost_trivial = boost::log::trivial;

/*
* 自定义日志等级
*/
enum sign_severity_level {
    trace = 0,
    debug,
    info,
    warn,
    error,
    fatal,
    callback
};

#define BOOST_TRACE\
    BOOST_LOG_SEV((BoostLog::s_slg), (trace)) << __FILE__ << "[" << __LINE__ << "]:"
#define BOOST_DEBUG\
    BOOST_LOG_SEV((BoostLog::s_slg), (debug)) << __FILE__ << "[" << __LINE__ << "]:"
#define BOOST_INFO\
    BOOST_LOG_SEV((BoostLog::s_slg), (info)) << __FILE__ << "[" << __LINE__ << "]:"
#define BOOST_WARNING\
    BOOST_LOG_SEV((BoostLog::s_slg), (warn)) << __FILE__ << "[" << __LINE__ << "]:"
#define BOOST_ERROR\
    BOOST_LOG_SEV((BoostLog::s_slg), (error)) << __FILE__ << "[" << __LINE__ << "]:"
#define BOOST_FATAL\
    BOOST_LOG_SEV((BoostLog::s_slg), (fatal)) << __FILE__ << "[" << __LINE__ << "]:"
#define BOOST_CB\
    BOOST_LOG_SEV((BoostLog::s_slg), (callback)) << __FILE__ << "[" << __LINE__ << "]:"

#define RUDP_LOG(level, ...) \
    BoostLog::Log(level, ...)


// The formatting logic for the severity level
template< typename CharT, typename TraitsT >
inline std::basic_ostream< CharT, TraitsT >& operator<< (
    std::basic_ostream< CharT, TraitsT >& strm, sign_severity_level lvl)
{
    static const char* const str[] =
    {
        "trace",
        "debug",
        "info",
        "warn",
        "error",
        "fatal",
        "callback"
    };
    if (static_cast< std::size_t >(lvl) < (sizeof(str) / sizeof(*str)))
        strm << str[lvl];
    else
        strm << static_cast< int >(lvl);
    return strm;
}

/*
自定义日志类,在使用之前必须先调用 init方法;
写日志可以调用如下方法:
LOG_DEBUG<<"test string";
也可以用boost 中的宏  BOOST_LOG_TRIVIAL(info)<<"test msg";
*/
class BoostLog
{
public:
    BoostLog(){};
    ~BoostLog(void){ Uninit();}

    /*! 在使用此类之前必须先调用此函数进行初始化工作;
    * Init_Debug 会添加控制台输出和日志文件输出;
    * param@dir : 日志文件存放目录
    * param@fileName : 日志文件名前缀
    * param@level : 日志过滤等级
    * */
    static void Init_Debug(const string & dir, const string & fileName, sign_severity_level level)
    {
        if (_init_flag)
        {
            return;
        }else
        {
            _init_flag = true;
        }
        if (boost::filesystem::exists(dir) == false)
        {
            boost::filesystem::create_directories(dir);
        }
        //日志名后添加_进程ID,以区分不同进程,防止冲突
        string tmp_str = (boost::format("%s_%d") %fileName % getpid()).str();
        AddConsoleSink();
        AddFileSink(dir, tmp_str);
        boost_log::add_common_attributes();
        //设置日志过滤等级
        SetLogLevel(level);
    }

    /*! 在使用此类之前必须先调用此函数进行初始化工作;
    * Init_Release 添加日志文件输出sink;
    * param@dir : 日志文件存放目录
    * param@fileName : 日志文件名前缀
    * param@level : 日志过滤等级
    */
    static void Init_Release(const string & dir, const string & fileName, sign_severity_level level)
    {
        if (_init_flag)
        {
            return;
        }else
        {
            _init_flag = true;
        }

        if (boost::filesystem::exists(dir) == false)
        {
            boost::filesystem::create_directories(dir);
        }
        //日志名后添加_进程ID,以区分不同进程,防止冲突
        string tmp_str = (boost::format("%s_%d") %fileName % getpid()).str();
        AddFileSink(dir, tmp_str);
        boost_log::add_common_attributes();
        //设置日志过滤等级
        SetLogLevel(level);
    }

    static void Uninit()
    {
        if (!_init_flag)
        {
            return;
        }else
        {
            _init_flag = false;
        }
        boost_log::core::get()->flush();
        boost_log::core::get()->remove_all_sinks();
    }

    static void SetLogLevel(sign_severity_level level)
    {
        boost_log::core::get()->set_filter(boost_expressions::attr< sign_severity_level >("Severity") >= level);
    }

    static void Log(sign_severity_level level_, const char* fmt, ...)
    {
        char str_buf[1024] = {0};
        memset(str_buf, 0, sizeof(str_buf));
        va_list ap;
        va_start(ap, fmt);
        vsprintf_s(str_buf, fmt, ap);
        va_end(ap);
        switch (level_)
        {
        case trace:
            BOOST_TRACE << str_buf;
            break;
        case debug:
            BOOST_DEBUG << str_buf;
            break;
        case info:
            BOOST_INFO << str_buf;
            break;
        case warn:
            BOOST_WARNING << str_buf;
            break;
        case error:
            BOOST_ERROR << str_buf;
            break;
        case fatal:
            BOOST_FATAL << str_buf;
            break;
        case callback:
            BOOST_CB << str_buf;
            break;
        default:
            break;
        }
    }

protected:
    static void Start(){ boost_log::core::get()->set_logging_enabled(true); }
    static void Stop(){ boost_log::core::get()->set_logging_enabled(false); }

    //打印在控制台    
    static void AddConsoleSink()
    {
        boost_log::add_console_log()->set_formatter(
            boost_expressions::format("[%1%]<%2%>(%3%): %4%")
            % boost_expressions::format_date_time< boost::posix_time::ptime >("TimeStamp", "%H:%M:%S.%f")
            % boost_expressions::attr<sign_severity_level>("Severity")
            % boost_expressions::attr<boost_attributes::current_thread_id::value_type >("ThreadID")
            % boost_expressions::smessage
            );
    }
    //输出至日志文件
    static void AddFileSink(const string & dir, const string & fileName)
    {
        typedef boost_sinks::synchronous_sink< boost_sinks::text_file_backend > sink_t;
        boost::shared_ptr< sink_t > pFileSink = boost_log::add_file_log(
            boost_keywords::open_mode = std::ios::/*app*/trunc,
            boost_keywords::file_name = dir + "/" + fileName + "_%Y-%m-%d(%N).log",
            boost_keywords::rotation_size = 10 * 1024 * 1024,
            boost_keywords::time_based_rotation = boost_sinks::file::rotation_at_time_point(0, 0, 0), //间隔多长时间自动新建文件
            boost_keywords::format =
            (
            boost_expressions::stream
            << "[" << boost_expressions::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << "]"
            << "<" << boost_expressions::attr<sign_severity_level>("Severity") << ">"
            //<< "(" << boost_expressions::attr< boost::log::aux::thread::id >("ThreadID") << ")"
            << boost_expressions::smessage
            )
            );

        pFileSink->locked_backend()->set_file_collector(boost_sinks::file::make_collector(
            boost_keywords::target = dir + "/oldlogs",                //目标文件夹
            boost_keywords::max_size = 100 * 1024 * 1024,        //所有日志加起来的最大大小,
            boost_keywords::min_free_space = 1000 * 1024 * 1024  //最低磁盘空间限制
            ));

        pFileSink->locked_backend()->auto_flush(true);//使日志实时更新
        pFileSink->locked_backend()->scan_for_files();
    }

public:
    static boost_sources::severity_logger< sign_severity_level> s_slg;

protected:
    static bool _init_flag;
};


boost_log.cpp

#include "boost_log.h"

boost_sources::severity_logger< sign_severity_level > BoostLog::s_slg;
bool BoostLog::_init_flag = false;

注意事项:

由于类中均为静态变量,所以一个模块只能写一个日志文件,这也是这个日志类的一个弊端;

不要多个模块同时写同一个名字的文件,否则在对文件进行关闭操作时会导致程序异常;

boost编译为静态库,因boost使用的是动态链接技术,所以在win32代码中不需要手动添加任何静态链接各种lib的代码,只需要在工程中指定库目录即可。

转载于:https://my.oschina.net/superfather/blog/781199

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值