架构设计 - 日志管理接口设计
Posted 白驹过隙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构设计 - 日志管理接口设计相关的知识,希望对你有一定的参考价值。
在后端代码中,日志无处不在,自己设计自己的一套日志管理代码,提供一套好用的日志接口将大大方便代码的开发。
其中在日志管理代码的编写中,主要有以下难点:
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 <[email protected]> 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
以上是关于架构设计 - 日志管理接口设计的主要内容,如果未能解决你的问题,请参考以下文章
Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段
tornado项目之基于领域驱动模型架构设计的京东用户管理后台