zoukankan      html  css  js  c++  java
  • 架构设计

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

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

    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.0
    10 *
    11 *  Github/Mail: https://github.com/binchen-china    <563853086@qq.com>
    12 *
    13 *  Note:
    14 */
    15 //=============================================================================
    16 
    17 #pragma once
    18 #include "DMaker.h"
    19 
    20 enum LOG_LEVEL
    21 {
    22     DM_ERROR = 0x0001,
    23     DM_WARNING  = 0x0010,
    24     DM_INFO = 0x0100,
    25     DM_DEBUG = 0x1000
    26 };
    27 
    28 class DMLogManager
    29 {
    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 info
    62 #define DM_PRINT(LOG_FMT,args...) DMLogMgr::instance()->print_log(LOG_FMT,##args)
    63 //console output with code info
    64 #define DM_TRACE(LOG_FMT,args...) DMLogMgr::instance()->trace_log(__FILE__,__FUNCTION__,__LINE__,LOG_FMT,##args)
    65 //write logs into log file
    66 #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

  • 相关阅读:
    Centos下安装部署redis
    mysql 事务操作
    python 基础杂货铺
    6、Django 第三方工具
    5、Django
    4、django 模板
    RPC框架--missian框架
    jvm详情——7、jvm调优基本配置、方案
    jvm详情——6、堆大小设置简单说明
    jvm详情——5、选择合适的垃圾收集算法
  • 原文地址:https://www.cnblogs.com/binchen-china/p/5852639.html
Copyright © 2011-2022 走看看