在后端代码中,日志无处不在,设计一套自己的日志管理代码,给框架提供一套好用的日志接口将大大方便代码的开发。
其中在日志管理代码的编写中,主要有以下难点:
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