在後端代碼中,日誌無處不在,設計一套本身的日誌管理代碼,給框架提供一套好用的日誌接口將大大方便代碼的開發。git
其中在日誌管理代碼的編寫中,主要有如下難點:github
1.數目不肯定的入參函數編寫後端
2.日誌權限控制app
3.日誌輸出形式。框架
接口設計:函數
1.提供三類日誌打印形式:1)控制檯打印信息,相似printf的接口封裝spa
2)函數追蹤接口,打印當前代碼的文件名,函數名及行,以及一些設定的輸出參數設計
3)日誌打印函數,提供打印級別控制,且打印內容輸出到日誌文件中日誌
2.提供日誌級別控制:1)在打印日誌時提供當前日誌級別,代碼依據級別進行控制打印code
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