首页 > 代码库 > 架构设计 - 日志管理接口设计

架构设计 - 日志管理接口设计

在后端代码中,日志无处不在,自己设计自己的一套日志管理代码,提供一套好用的日志接口将大大方便代码的开发。

其中在日志管理代码的编写中,主要有以下难点:

 

1.数目不确定的入参函数编写

2.日志权限控制

3.日志输出形式。

 

接口设计:

1.提供三类日志打印形式:1)控制台打印信息,类似printf的接口封装

            2)函数追踪接口,打印当前代码的文件名,函数名及行,以及一些设定的输出参数

            3)日志打印函数,提供打印级别控制,且打印内容输出到日志文件中

2.提供日志级别控制:1)在打印日志时提供当前日志级别,代码依据级别进行控制打印

          2)日志打印级别控制暂时使用配置文件,后续可以通过通信接口进行实时修改

 

下面附上代码实现:DMLogManager.h

 1 //============================================================================= 2 /*  3 *  File: DMLogManager.h 4 * 5 *  Author: bing 6 * 7 *  Date: 2016-09-07 8 * 9 *  Version: v2.010 *11 *  Github/Mail: https://github.com/binchen-china    <563853086@qq.com>12 *13 *  Note:14 */15 //=============================================================================16 17 #pragma once18 #include "DMaker.h"19 20 enum LOG_LEVEL21 {22     DM_ERROR = 0x0001,23     DM_WARNING  = 0x0010,24     DM_INFO = 0x0100,25     DM_DEBUG = 0x100026 };27 28 class DMLogManager29 {30 public:31     DMLogManager();32     33     ~DMLogManager();34 35     void print_log(const DM_CHAR* fmt, ...);36    37     void trace_log(string file, string func, DM_INT line, const DM_CHAR* fmt, ...);38           39     void write_log(DM_INT log_level, string file, string func, DM_INT line, const DM_CHAR* fmt, ...);40     41 private:42     void init();43 44     void get_log_config();45     46     inline void open_log_file();47     48     inline void close_log_file();49     50     void set_log_level();51 52 private:53     FILE* _log_file;54     string _log_name;55     string _log_level;56     DM_INT _log_mask;57 };58 59 typedef ACE_Singleton<DMLogManager, ACE_Thread_Mutex> DMLogMgr;60 61 //console output without code info62 #define DM_PRINT(LOG_FMT,args...) DMLogMgr::instance()->print_log(LOG_FMT,##args)63 //console output with code info64 #define DM_TRACE(LOG_FMT,args...) DMLogMgr::instance()->trace_log(__FILE__,__FUNCTION__,__LINE__,LOG_FMT,##args)65 //write logs into log file66 #define DM_LOG(LOG_LEVEL,LOG_FMT,args...) DMLogMgr::instance()->write_log(LOG_LEVEL,__FILE__,__FUNCTION__,__LINE__,LOG_FMT,##args)

 

DMLogManager.cpp

#include "DMLogManager.h"DMLogManager::DMLogManager():_log_mask(0){    init();}DMLogManager::~DMLogManager(){    }void DMLogManager::init(){    get_log_config();     set_log_level();}void DMLogManager::get_log_config(){    _log_name = DMJsonCfg::instance()->GetItemString("service_info", "service_name");    _log_level = DMJsonCfg::instance()->GetItemString("service_info", "log_level");    _log_name.append(".log");}inline  void DMLogManager::open_log_file(){    _log_file = fopen(_log_name.c_str(), "a");    if (nullptr == _log_file)    {            return;    }    }inline  void DMLogManager::close_log_file(){    fclose(_log_file);}void DMLogManager::set_log_level(){    if ("DEBUG" == _log_level)    {        _log_mask = 0x1111;    }    else if ("INFO" == _log_level)    {        _log_mask = 0x0111;    }    else if ("WARNING" == _log_level)    {        _log_mask = 0x0011;    }    else if ("ERROR" == _log_level)    {        _log_mask = 0x0001;    }}void DMLogManager::print_log(const DM_CHAR* fmt, ...){    va_list ap;    va_start(ap, fmt);                   string log_info = fmt;         ACE_OS::vfprintf(stdout, fmt, ap);      va_end (ap);}void DMLogManager::trace_log(string file, string func, DM_INT line, const DM_CHAR* fmt, ...){    va_list ap;    va_start(ap, fmt);                   ACE_OS::printf("[DM_TRACE][%s][%s][%d]:",file.c_str(), func.c_str(), line);                   string log_info = fmt;         ACE_OS::vfprintf(stdout, fmt, ap);      va_end (ap);}void DMLogManager::write_log(DM_INT log_level, string file, string func, DM_INT line, const DM_CHAR* fmt, ...){    va_list ap;    va_start(ap, fmt);        open_log_file();        switch (log_level)    {        case DM_DEBUG:        {            if (DM_DEBUG & _log_mask)            {                               ACE_OS::fprintf(_log_file, "[DM_DEBUG][%s][%s][%d]:",file.c_str(), func.c_str(), line);                                 ACE_OS::vfprintf(_log_file, fmt, ap);              }                        break;        }        case DM_INFO:        {            if (DM_INFO & _log_mask)            {                ACE_OS::fprintf(_log_file, "[DM_INFO][%s][%s][%d]:",file.c_str(), func.c_str(), line);                                  ACE_OS::vfprintf(_log_file, fmt, ap);              }            break;        }        case DM_WARNING:        {            if (DM_WARNING & _log_mask)            {                ACE_OS::fprintf(_log_file, "[DM_WARNING][%s][%s][%d]:",file.c_str(), func.c_str(), line);                                 ACE_OS::vfprintf(_log_file, fmt, ap);              }            break;        }        case DM_ERROR:        {            if (DM_ERROR & _log_mask)            {                ACE_OS::fprintf(_log_file, "[DM_ERROR][%s][%s][%d]:",file.c_str(), func.c_str(), line);                                 ACE_OS::vfprintf(_log_file, fmt, ap);                   }            break;        }    }        close_log_file();    va_end (ap);}

 

更多技术信息请关注github:https://github.com/binchen-china

架构设计 - 日志管理接口设计