简单的log日志

鉴于任何功能模块或系统在调试时都需要日志打印,这里随便写了一下,作为以后代码调试之用,只实现了不同等级的日志输出功能,其他的调试功能以后再行添加;使用方法简单,只需要在头文件里事先按照log的输出等级定义几个宏即可,然后就可以在源码文件中直接使用了,后面附上使用例程;

源码如下:

LogC.h

  1. #ifndef __LOG_SYSTEM_H__
  2. #define __LOG_SYSTEM_H__
  3.  
  4. #include <inttypes.h>
  5.  
  6. /** 错误码基数 **/
  7. #define ErrorCode_Base 100
  8.  
  9. /** 模块列表大小 **/
  10. #define MODULE_LIST_SIZE 32
  11.  
  12. /**
  13. * Date & Time output:
  14. 0: no output
  15. 1: output date
  16. 2: output time
  17. 3: output date&time
  18. **/
  19. #define OUTPUTFlag_DateTime 3
  20.  
  21. /**
  22. * MachineInfo output:
  23. 0: no output
  24. 1: output mac
  25. 2: output ip
  26. 3: output mac&ip
  27. **/
  28. #define OUTPUTFlag_MachineInfo 2
  29.  
  30. /**
  31. * Version output:
  32. 0: no version output
  33. 1: output Major_Version_Number
  34. 2: output Minor_Version_Number
  35. 4: output Revision_Number[Build_Number]
  36. 8: output currentModule_Version_Number
  37.  
  38. 3: output Major_Version_Number & Minor_Version_Number
  39. 7: output Major_Version_Number & Minor_Version_Number & Revision_Number[Build_Number]
  40. 15: output all
  41. **/
  42. #define OUTPUTFlag_Version 15
  43.  
  44. /**
  45. * ModuleName output:
  46. 0: no output
  47. 1: output CurrentModule_Name
  48. **/
  49. #define OUTPUTFlag_ModuleName 1
  50.  
  51. /***
  52. * LogLevel:
  53. * "Assert" : 0
  54. * "Fatal!" : 1
  55. * "Error!" : 2
  56. * "Warning" : 3
  57. * "Info" : 4
  58. * "Verbose : 5
  59. * "Debug" : 6
  60. * "Undefined" : default
  61. ***/
  62. #define LogFatal(moduleNO, level, args...) \
  63. do { \
  64. if (level >= LOG_LEVEL_Fatal) \
  65. logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Fatal, args); \
  66. } while(0)
  67.  
  68. #define LogError(moduleNO, level, args...) \
  69. do { \
  70. if (level >= LOG_LEVEL_Error) \
  71. logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Error, args); \
  72. } while(0)
  73.  
  74. #define LogWarning(moduleNO, level, args...) \
  75. do { \
  76. if (level >= LOG_LEVEL_Warning) \
  77. logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Warning, args); \
  78. } while(0)
  79.  
  80. #define LogInfo(moduleNO, level, args...) \
  81. do { \
  82. if (level >= LOG_LEVEL_Info)\
  83. logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Info, args); \
  84. } while(0)
  85.  
  86. #define LogVerbose(moduleNO, level, args...) \
  87. do { \
  88. if (level >= LOG_LEVEL_Verbose) \
  89. logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Verbose, args); \
  90. } while(0)
  91.  
  92. #define LogDebug(moduleNO, level, args...) \
  93. do { \
  94. if (level >= LOG_LEVEL_Debug) \
  95. logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Debug, args); \
  96. } while(0)
  97.  
  98. /**
  99. * 时间:年-月-日-星期几 时-分-秒-毫秒
  100. * 格式:
  101. * [month-day-year, weekday][hour:min:sec.msec]
  102. **/
  103. typedef struct DT {
  104. uint16_t mYear; //!< e.g. 2005
  105. uint8_t mMonth; //!< 1...12
  106. uint8_t mDayOfWeek; //!< 0...6, 0==Sunday
  107. uint8_t mDay; //!< 1...31
  108. uint8_t mHour; //!< 0...23
  109. uint8_t mMinute; //!< 0...59
  110. uint8_t mSecond; //!< 0...59
  111. uint32_t muSecond; //!< 0...999999
  112. } DateTime;
  113.  
  114. /**
  115. * 版本号: Major . Minor . BuildVersion : currentModuleVersion
  116. * Major : 主版本号
  117. * Minor : 子版本号
  118. * BuildVersion : 修正版本号 或 编译版本号
  119. **/
  120. typedef struct _Version {
  121. int Major; // 主版本号
  122. int Minor; // 子版本号
  123. int BuildVersion; // 编译版本号 或者 修正版本号
  124. } Version_t;
  125.  
  126. /**
  127. * 日志类型:
  128. * 针对某一模块,设置日志种类;
  129. **/
  130. typedef enum _LogType {
  131. LogType_SYSTEM = 0x01, /** 系统相关日志 **/
  132. LogType_SECURITY = 0x02, /** 安全相关日志 **/
  133. LogType_RUNNING = 0x04, /** 运行时日志 **/
  134. LogType_OPERATION = 0x08, /** 操作型日志 **/
  135. LogType_ALL = LogType_OPERATION | LogType_RUNNING | LogType_SECURITY | LogType_SYSTEM /** 所有类型日志 **/
  136. }LogType;
  137.  
  138. /**
  139. * 模块列表:
  140. * 模块名 . 模块日志等级 . 模块日志类型
  141. ***/
  142. typedef struct moduleInfo{
  143. char name[12];
  144. char version[8];
  145. LogType logType;
  146. } ModuleInfo_t;
  147.  
  148. /**
  149. * 在代码中使用了不同等级的log输出宏函数,要控制日至输出的多少,只需要设置logLevel的等级即可;
  150. * 等级越高(或者说是值越大),可输出的log越多,举例:
  151. * 当logLevel设置为 LOG_LEVEL_INFO ,即 level = 3 时,在代码中设置的 level = 4(或是使用
  152. * MODULE_LOG_VERBOSE()宏函数)的打印日志不能输出,设置为 level <= 3(或是使用MODULE_LOG_ERROR(),
  153. * MODULE_LOG_WARNING(),MODULE_LOG()宏函数)的日志都可以输出;
  154. * 详细说明参考以下代码;
  155. **/
  156. enum LogLevel {
  157. LOG_LEVEL_Assert = 0x00, /** for pre-compile print log **/
  158. LOG_LEVEL_Fatal = 0x01,
  159. LOG_LEVEL_Error = 0x02, /** **/
  160. LOG_LEVEL_Warning = 0x03, /** **/
  161. LOG_LEVEL_Info = 0x04, /** **/
  162. LOG_LEVEL_Verbose = 0x05, /** **/
  163. LOG_LEVEL_Debug = 0x06,
  164. LOG_LEVEL_Undefined
  165. };
  166.  
  167. #ifdef __cplusplus
  168. extern "C" {
  169. #endif
  170.  
  171. /***
  172. * 注册模块到 g_moduleList
  173. * 返回 当前模块在g_moduleList列表中的位置
  174. * g_moduleCount表示当前注册拥有的module数量
  175. **/
  176. int registerModule(char* name, char* version, int logtype);
  177.  
  178. /***
  179. 输出格式:
  180. [month-day-year, weekday][hour:min:sec.msec] [HostMac][HostName][Major.Minor.BuildVersion:ModuleVersion] [Module][file:line][function:log_level] : logBuffer_info.
  181. ***/
  182. void logVerboseCStyle(const char* file, int line, const char* function, int module, int level, const char* fmt, ...);
  183.  
  184. #ifdef __cplusplus
  185. }
  186. #endif
  187.  
  188. #endif

  

LogC.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5.  
  6. #include <time.h>
  7. #include <sys/time.h>
  8.  
  9. #include <sys/socket.h>
  10. #include <sys/ioctl.h>
  11. #include <netinet/if_ether.h>
  12. #include <net/if.h>
  13. #include <linux/sockios.h>
  14. #include <unistd.h>
  15. #include <arpa/inet.h>
  16.  
  17. #include "LogC.h"
  18.  
  19. /**
  20. LogLevel: "Assert", "Fatal!", "Error!", "Warning", "Info", "Verbose", "Debug", "Undefined"
  21. 无 1 1 3 4 2 2 无
  22. 转义序列相关的常用参数如下(通过man console_codes命令可查看更多的参数描述):
  23. 显示:0(默认)、1(粗体/高亮)、22(非粗体)、4(单条下划线)、24(无下划线)、5(闪烁)、25(无闪烁)、7(反显、翻转前景色和背景色)、27(无反显)
  24. 颜色:0(黑)、1(红)、2(绿)、 3(黄)、4(蓝)、5(洋红)、6(青)、7(白)
  25. 前景色为30+颜色值,如31表示前景色为红色;背景色为40+颜色值,如41表示背景色为红色。
  26. **/
  27. static const uint8_t color[] = {0, 0x41, 0x41, 0x43, 0x04, 0x02, 0x02, 0x02};
  28. #define setLogColor(x) \
  29. { \
  30. if(x < 4) \
  31. fprintf(stderr, "\033[1;%d;3%dm", color[x]>>4, color[x]&15); \
  32. else \
  33. fprintf(stderr, "\033[%d;3%dm", color[x]>>4, color[x]&15); \
  34. }
  35. #define resetLogColor() fprintf(stderr, "\033[0m")
  36.  
  37. /** 日志level名称 **/
  38. static const char *textLogLevel[] = {"Assert", "Fatal!", "Error!", "Warning", "Info", "Verbose", "Debug", "Undefined"};
  39.  
  40. /** 日期字符串:月份 & 星期 **/
  41. static const char *monthStr[] = {"Reserved", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Undefined"};
  42. static const char *weekStr[] = {"Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat.", "Undefined"};
  43.  
  44. /**
  45. * 用于保存模块的列表: 列表大小MODULE_LIST_SIZE指定;
  46. * g_moduleCount 用于记录下次添加模块是的起始位置
  47. **/
  48. static struct moduleInfo g_moduleList[MODULE_LIST_SIZE] = {};
  49. static int g_moduleCount = 0;
  50.  
  51. /** g_version 使用——Version结构记录全局的版本号 **/
  52. struct _Version g_version;
  53.  
  54. /**
  55. * 获取当前时间:年-月-日-星期几 时-分-秒-毫秒
  56. * 输出格式:
  57. * [month-day-year, weekday][hour:min:sec.msec]
  58. * flag: 0: no output
  59. 1: output date
  60. 2: output time
  61. 3: output date&time
  62. **/
  63. static int get_CurrentTime(char *buf, int flag)
  64. {
  65. if (flag == 0)
  66. return 0;
  67.  
  68. static DateTime sDTime;
  69. struct timeval current;
  70. struct tm tempTime;
  71.  
  72. if (!gettimeofday(&current, NULL)) {
  73. localtime_r(&current.tv_sec, &tempTime);
  74. sDTime.mYear = tempTime.tm_year + 1900;
  75. sDTime.mMonth = tempTime.tm_mon + 1;
  76. sDTime.mDayOfWeek = tempTime.tm_wday;
  77. sDTime.mDay = tempTime.tm_mday;
  78. sDTime.mHour = tempTime.tm_hour;
  79. sDTime.mMinute = tempTime.tm_min;
  80. sDTime.mSecond = tempTime.tm_sec;
  81. sDTime.muSecond = current.tv_usec;
  82. }
  83.  
  84. if (flag & 0x01)
  85. sprintf(buf, "[%s-%02d-%04d, %s]", monthStr[sDTime.mMonth], sDTime.mDay, sDTime.mYear, weekStr[sDTime.mDayOfWeek]);
  86. if (flag & 0x02)
  87. sprintf(buf + strlen(buf), "[%02d:%02d:%02d.%03d] ", sDTime.mHour, sDTime.mMinute, sDTime.mSecond, sDTime.muSecond / 1000);
  88.  
  89. //printf("get_CurrentTime: buf[%s]...\n", buf);
  90. return strlen(buf);
  91. }
  92.  
  93. /**
  94. * 获取设备信息: mac,hostname,ip,串号等
  95. * flag: 0: no output
  96. 1: output mac
  97. 2: output ip
  98. 3: output mac&ip
  99. **/
  100. static int get_MachineInfo(const char *device, char *buf, int flag)
  101. {
  102. if (flag == 0)
  103. return 0;
  104.  
  105. unsigned char macAddr[6] = {0}; //6是MAC地址长度
  106. unsigned char ipAddr[18] = {0};
  107. unsigned char hostName[32] = {0};
  108. int sockfd;
  109. struct ifreq ifr4dev;
  110.  
  111. sockfd = socket(AF_INET, SOCK_DGRAM, 0); //internet协议族的数据报类型套接口
  112. strncpy(ifr4dev.ifr_name, device, sizeof(ifr4dev.ifr_name) - 1); //将设备名作为输入参数传入
  113.  
  114. //获取MAC地址
  115. ifr4dev.ifr_hwaddr.sa_family = ARPHRD_ETHER; //此处需要添加协议,网络所传程序没添加此项获取不了mac。
  116. if (ioctl(sockfd, SIOCGIFHWADDR, &ifr4dev) == -1) {
  117. printf("get_MachineInfo: get device [%s] mac error.\n", device);
  118. return -1;
  119. }
  120. memcpy(macAddr, ifr4dev.ifr_hwaddr.sa_data, ETH_ALEN);
  121.  
  122. //获取ip地址
  123. if (ioctl(sockfd, SIOCGIFADDR, &ifr4dev) == -1) {
  124. printf("get_MachineInfo: get device [%s] ip error.\n", device);
  125. return -1;
  126. }
  127. /**
  128. struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,
  129. 二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
  130. 一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。
  131. **/
  132. struct sockaddr_in *sin = (struct sockaddr_in *)&ifr4dev.ifr_addr;
  133. strcpy((char *)ipAddr, inet_ntoa(sin->sin_addr));
  134. close(sockfd);
  135.  
  136. //get hostName
  137. gethostname((char *)hostName, sizeof(hostName));
  138. sprintf(buf, "[%s]", hostName);
  139.  
  140. if (flag & 0x01)
  141. sprintf(buf + strlen(buf), "[%02x:%02x:%02x:%02x:%02x:%02x] ", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
  142. if (flag & 0x02)
  143. sprintf(buf + strlen(buf) - 1, "[%s] ", ipAddr);
  144.  
  145. //printf("get_MachineInfo: mac&ip buf=[%s]\n", buf);
  146. return (int)strlen(buf);
  147. }
  148.  
  149. /**
  150. * 获取版本号: Major.Minor.BuildVersion:currentModuleVersion
  151. 主版本号 . 子版本号 [. 修正版本号 或 编译版本号 ] : 当前模块版本号
  152. * flag: 0: no version output
  153. 1: output Major_Version_Number
  154. 2: output Minor_Version_Number
  155. 4: output Revision_Number[Build_Number]
  156. 8: output currentModule_Version_Number
  157.  
  158. 3: output Major_Version_Number & Minor_Version_Number
  159. 7: output Major_Version_Number & Minor_Version_Number & Revision_Number[Build_Number]
  160. 15: output all
  161. *
  162. * 注: 需要预先将版本号填充到 _Version 结构体
  163. **/
  164. static int get_Version(char *buf, int module, int flag)
  165. {
  166. if ((flag == 0) || (flag == 5) || (flag == 6) || ((8 < flag) && (flag < 15)) || (flag > 15))
  167. return 0;
  168. char tmp_currentModuleVersion[12] = {};
  169.  
  170. if (g_version.BuildVersion == 0) {
  171. g_version.Major = 0;
  172. g_version.Minor = 0;
  173. g_version.BuildVersion = 0;
  174. }
  175.  
  176. sprintf(buf, "%s", "[");
  177. if (flag & 0x01)
  178. sprintf(buf + strlen(buf), "%d", g_version.Major);
  179. if (flag & 0x02)
  180. sprintf(buf + strlen(buf), ".%d", g_version.Minor);
  181. if (flag & 0x04)
  182. sprintf(buf + strlen(buf), ".%d", g_version.BuildVersion);
  183. if (flag & 0x08) {
  184. strcpy(tmp_currentModuleVersion, g_moduleList[module].version);
  185. sprintf(buf + strlen(buf), ":%s", tmp_currentModuleVersion);
  186. }
  187. sprintf(buf + strlen(buf), "%s", "]");
  188.  
  189. //printf("get_Version: buf[%s]\n", buf);
  190. return strlen(buf);
  191. }
  192.  
  193. /***
  194. * 注册模块到 g_moduleList 列表
  195. * 返回 当前模块在g_moduleList列表中的位置;
  196. * g_moduleCount 表示当前列表中已注册的(已拥有的)module数量;
  197. **/
  198. int registerModule(char *name, char *version, int logtype)
  199. {
  200. int k = 0;
  201. if (g_moduleCount < 0 || g_moduleCount >= MODULE_LIST_SIZE)
  202. return -1;
  203.  
  204. strncpy((char *)&g_moduleList[g_moduleCount].name, name, 12);
  205. strncpy((char *)&g_moduleList[g_moduleCount].version, version, 8);
  206. g_moduleList[g_moduleCount].logType = logtype;
  207.  
  208. k = g_moduleCount;
  209. g_moduleCount++;
  210.  
  211. return k;
  212. }
  213.  
  214. /**
  215. * 从模块列表中获取当前模块名:
  216. * flag: 0: no output
  217. 1: output CurrentModule_Name
  218. *
  219. * 注: 需要预先将模块注册
  220. **/
  221. static int get_CurrentModuleName(char *buf, int module, int flag)
  222. {
  223. if (flag == 0)
  224. return 0;
  225. if (module < 0 || module >= MODULE_LIST_SIZE)
  226. return -1;
  227.  
  228. if (0 != strcmp(g_moduleList[module].name, "")) {
  229. sprintf(buf, "[%s] ", g_moduleList[module].name);
  230. } else {
  231. sprintf(buf, "[%s] ", "0000000");
  232. }
  233.  
  234. //printf("get_CurrentModuleName: buf[%s]\n", buf);
  235. return strlen(buf);
  236. }
  237.  
  238. /**
  239. * 计算出错误码值:
  240. * 计算出的 errorcode 是大于 ErrorCode_Base 的
  241. * 计算出的 errorcode 区间(数字从小到大): system--security--running--operation
  242. **/
  243. static int get_ErrorCode(char *buf, int module, int level)
  244. {
  245. int logtype = 0;
  246. int errcode = 0;
  247.  
  248. if ((module < 0 || module >= MODULE_LIST_SIZE) || (0 == strcmp(g_moduleList[module].name, "")))
  249. return -1;
  250.  
  251. logtype = g_moduleList[module].logType;
  252.  
  253. //TODO: 根据一定规则,由logtype和loglevel计算出errorcode值;
  254. switch (logtype) {
  255. case LogType_OPERATION: /** operation type error **/
  256. errcode = ErrorCode_Base + LogType_OPERATION * 8 + level;
  257. break;
  258. case LogType_RUNNING: /** running type error **/
  259. errcode = ErrorCode_Base + LogType_RUNNING * 8 + level;
  260. break;
  261. case LogType_SECURITY: /** security type error **/
  262. errcode = ErrorCode_Base + LogType_SECURITY * 8 + level;
  263. break;
  264. case LogType_SYSTEM: /** system type error **/
  265. errcode = ErrorCode_Base + LogType_SYSTEM * 8 + level;
  266. break;
  267. case LogType_ALL: /** all type error **/
  268. errcode = ErrorCode_Base + LogType_ALL * 8 + level;
  269. break;
  270. default:
  271. printf("get_ErrorCode: logtype [%d] is error.\n", logtype);
  272. break;
  273. }
  274. sprintf(buf, "<<%d>> ", errcode);
  275.  
  276. //printf("get_ErrorCode: buf[%s]\n", buf);
  277. return strlen(buf);
  278. }
  279.  
  280. /**
  281. * 设置log输出颜色并输出:
  282. * 日志level : 颜色及输出设置:
  283. "Fatal!" 1(粗体/高亮)、4(单条下划线)、1(红)
  284. "Error!" 1(粗体/高亮)、4(单条下划线)、1(红)
  285. "Warning" 1(粗体/高亮)、4(单条下划线)、3(黄)
  286. "Info" 4(蓝)
  287. "Verbose" 2(绿)
  288. "Debug" 2(绿)
  289. **/
  290. static int useColor = -1;
  291. static int colored_LogOutput(int level, char *str)
  292. {
  293. if (useColor < 0) {
  294. useColor = !getenv("NO_COLOR") && !getenv("LOG_FORCE_NOCOLOR") && ((getenv("TERM") && isatty(1)) || getenv("LOG_FORCE_COLOR"));
  295. }
  296.  
  297. if (useColor)
  298. setLogColor(level);
  299. if ((level <= LOG_LEVEL_Assert) || (level >= LOG_LEVEL_Undefined)) {
  300. printf("colored_LogOutput: level is [%d],error.\n", level);
  301. fputs(str, NULL);
  302. } else
  303. fputs(str, stdout); //输出到stdout
  304. if (useColor)
  305. resetLogColor();
  306.  
  307. return 0;
  308. }
  309.  
  310. /**
  311. * 净化log输出信息:
  312. * 可输出的字符范围: 0x08(退格)———— 0x0D(回车键); 0x20(空格)———— 0x7F(删除)
  313. * 其他字符均使用 ‘?’替代输出;
  314. **/
  315. static void logLineSanitize(uint8_t *str)
  316. {
  317. int k = 0;
  318. while (*str) {
  319. if (*str < 0x08 || (*str > 0x0D && *str < 0x20)) {
  320. *str = '?';
  321. k++;
  322. }
  323. str++;
  324. }
  325. return ;
  326. }
  327.  
  328. /***
  329. 输出格式:
  330. [month-day-year, weekday][hour:min:sec.msec] [HostMac][HostIP] [Major.Minor.BuildVersion:ModuleVersion][ModuleName] [ErrorCode][file:line][function:LogLevel] : logBuffer_info.
  331. ***/
  332. void logVerboseCStyle(const char *file, int line, const char *function, int module, int level, const char *fmt, ...)
  333. {
  334. va_list args;
  335. char currTime[48] = {0};
  336. char machineInfo[64] = {0};
  337. char version[16] = {0};
  338. char moduleName[16] = {0};
  339. char errorCode[16] = {0};
  340. static char sLogBuffer[512] = { 0 };
  341. static char str[1024] = {0};
  342.  
  343. // date & time
  344. get_CurrentTime((char *)&currTime, OUTPUTFlag_DateTime);
  345.  
  346. // mac & ip
  347. get_MachineInfo("eth0", (char *)&machineInfo, OUTPUTFlag_MachineInfo);
  348.  
  349. // version
  350. get_Version((char *)&version, module, OUTPUTFlag_Version);
  351.  
  352. // module
  353. get_CurrentModuleName((char *)&moduleName, module, OUTPUTFlag_ModuleName);
  354.  
  355. // errorcode
  356. get_ErrorCode((char *)&errorCode, module, level);
  357.  
  358. va_start(args, fmt);
  359. vsnprintf(sLogBuffer, 512, fmt, args);
  360. va_end(args);
  361.  
  362. snprintf(str, strlen(currTime) + 1, "%s", currTime);
  363. snprintf(str + strlen(str), strlen(machineInfo) + 1, "%s", machineInfo);
  364. snprintf(str + strlen(str), strlen(version) + 1, "%s", version);
  365. snprintf(str + strlen(str), strlen(moduleName) + 1, "%s", moduleName);
  366. snprintf(str + strlen(str), strlen(errorCode) + 1, "%s", errorCode);
  367. sprintf(str + strlen(str), "[%s:%d][%s:%s] ", (strchr(file, '/') ? (strchr(file, '/') + 1) : file), line, function, textLogLevel[level]);
  368. sprintf(str + strlen(str), ": %s", sLogBuffer);
  369.  
  370. logLineSanitize((uint8_t *)str);
  371. colored_LogOutput(level, str);
  372. return ;
  373. }

  

简单的功能测试代码:

用于测试的源文件 logTest.c

  1. #include <stdio.h>
  2. #include "LogC.h"
  3.  
  4. #include "test/upgrade.h"
  5. #include "test/example.h"
  6.  
  7. extern struct _Version g_version;
  8.  
  9. int log_init()
  10. {
  11. //register to module list
  12. g_moduleUpgradeNO = registerModule(ModuleName_UPGRADE, ModuleVersion_UPGRADE, ModuleLogType_UPGRADE);
  13. g_moduleBuildNO = registerModule(ModuleName_BUILD, ModuleVersion_BUILD, ModuleLogType_BUILD);
  14.  
  15. return 0;
  16. }
  17.  
  18. int main()
  19. {
  20. //init g_version
  21. g_version.Major = 9;
  22. g_version.Minor = 88;
  23. g_version.BuildVersion = 777;
  24.  
  25. log_init();
  26.  
  27. upgradeLogFatal("=====upgradeLogFatal==[%d]=--------------=\n", g_moduleUpgradeNO);
  28. upgradeLogError("=====upgradeLogError==[%d]=--------------=\n", g_moduleUpgradeNO);
  29. upgradeLogWarning("=====upgradeLogWarning==[%d]=--------------=\n", g_moduleUpgradeNO);
  30. upgradeLogInfo("=====upgradeLogInfo==[%d]=--------------=\n", g_moduleUpgradeNO);
  31. upgradeLogVerbose("=====upgradeLogVerbose==[%d]=--------------=\n", g_moduleUpgradeNO);
  32. upgradeLogDebug("=====upgradeLogDebug==[%d]=--------------=\n", g_moduleUpgradeNO);
  33.  
  34. printf("==========================================\n");
  35. buildLogFatal("=====buildLogFatal==[%d]=--------------=\n", g_moduleBuildNO);
  36. buildLogError("=====buildLogError==[%d]=--------------=\n", g_moduleBuildNO);
  37. buildLogWarning("=====buildLogWarning==[%d]=--------------=\n", g_moduleBuildNO);
  38. buildLogInfo("=====buildLogInfo==[%d]=--------------=\n", g_moduleBuildNO);
  39. buildLogVerbose("=====buildLogVerbose==[%d]=--------------=\n", g_moduleBuildNO);
  40. buildLogDebug("=====buildLogDebug==[%d]=--------------=\n", g_moduleBuildNO);
  41.  
  42. return 0;
  43. }

  

事先按log等级定义好宏的头文件 example.h

  1. #ifndef __BUILD_H__
  2. #define __BUILD_H__
  3.  
  4. #include "LogC.h"
  5.  
  6. #define ModuleName_BUILD "build"
  7. #define ModuleVersion_BUILD "45343"
  8. #define ModuleLogType_BUILD LogType_ALL
  9.  
  10. /**
  11. * g_moduleBuildNO: 记录当前模块在模块列表中的位置
  12. * g_buildLogLevel: 设置当前模块的log输出等级,每个模块都可设置独立的log输出等级
  13. **/
  14. int g_moduleBuildNO = 0;
  15. static int g_buildLogLevel = LOG_LEVEL_Debug;
  16.  
  17. #define buildLogFatal(args...) LogFatal(g_moduleBuildNO, g_buildLogLevel, args)
  18. #define buildLogError(args...) LogError(g_moduleBuildNO, g_buildLogLevel, args)
  19. #define buildLogWarning(args...) LogWarning(g_moduleBuildNO, g_buildLogLevel, args)
  20. #define buildLogInfo(args...) LogInfo(g_moduleBuildNO, g_buildLogLevel, args)
  21. #define buildLogVerbose(args...) LogVerbose(g_moduleBuildNO, g_buildLogLevel, args)
  22. #define buildLogDebug(args...) LogDebug(g_moduleBuildNO, g_buildLogLevel, args)
  23.  
  24. #endif

  

还有一个 upgrade.h

  1. #ifndef __UPGRADE_H__
  2. #define __UPGRADE_H__
  3.  
  4. #include "LogC.h"
  5.  
  6. #define ModuleName_UPGRADE "upgrade"
  7. #define ModuleVersion_UPGRADE "1111"
  8. #define ModuleLogType_UPGRADE LogType_SECURITY
  9.  
  10. /**
  11. * g_moduleUpgradeNO: 记录当前模块在模块列表中的位置
  12. * g_upgradeLogLevel: 设置当前模块的log输出等级,每个模块都可设置独立的log输出等级
  13. **/
  14. int g_moduleUpgradeNO = 0;
  15. static int g_upgradeLogLevel = LOG_LEVEL_Debug;
  16.  
  17. #define upgradeLogFatal(args...) LogFatal(g_moduleUpgradeNO, g_upgradeLogLevel, args)
  18. #define upgradeLogError(args...) LogError(g_moduleUpgradeNO, g_upgradeLogLevel, args)
  19. #define upgradeLogWarning(args...) LogWarning(g_moduleUpgradeNO, g_upgradeLogLevel, args)
  20. #define upgradeLogInfo(args...) LogInfo(g_moduleUpgradeNO, g_upgradeLogLevel, args)
  21. #define upgradeLogVerbose(args...) LogVerbose(g_moduleUpgradeNO, g_upgradeLogLevel, args)
  22. #define upgradeLogDebug(args...) LogDebug(g_moduleUpgradeNO, g_upgradeLogLevel, args)
  23.  
  24. #endif

  

模块(二)——简单的log日志的更多相关文章

  1. C++简单实现Log日志类轻量级支持格式化输出变量

    CLog 头 代码很简单 如果需要的直接Ctrl+C  ----Ctrl+V 即可 #ifndef __CLOG__ #define __CLOG__ #include <windows.h&g ...

  2. Py修行路 python基础 (二十一)logging日志模块 json序列化 正则表达式(re)

    一.日志模块 两种配置方式:1.config函数 2.logger #1.config函数 不能输出到屏幕 #2.logger对象 (获取别人的信息,需要两个数据流:文件流和屏幕流需要将数据从两个数据 ...

  3. python的logging日志模块(二)

    晚上比较懒,直接搬砖了. 1.简单的将日志打印到屏幕   import logging logging.debug('This is debug message') logging.info('Thi ...

  4. 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块

    Log4a 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块 github地址 : https://github.com/EalenXie/log4a 在API每次被请求时 ...

  5. 韦大仙--简单的monkey测试命令行操作及生成log日志保存

    作中,在将apk交给软件测试人员去测试之前,不免要自己先自测,monkey自测是一个不错的选择! 步骤很简单: 1.测试用的手机与电脑连接好USB ,并且安装好驱动(我一般都是通过豌豆荚自动安装的)! ...

  6. python之log日志模块

    logging的配置大致有下面几种方式. 1.        通过代码进行完整配置,logging.getLogger()获取logger后,给logger设置各种handler. 2.       ...

  7. java最简单实现Log打印和生成日志文件

    导包 1.commons-logging.jar包 下载 2.log4j.jar包 下载 配置log4j 1.在src根目录下创建一个log4j.properties文件. 文件全部内容如下: log ...

  8. BIND的进阶二:视图,日志,转发,子域的授权

    实验分为4部分组成: 1:DNS的转发   2:DNS日志     3:子域的授权 4:智能DNS的简单配置根据网段来分配不同的ip地址 一:DNS的转发: 转发方式有两种:only (直接把客户端请 ...

  9. python之常用模块二(hashlib logging configparser)

    摘要:hashlib ***** logging ***** configparser * 一.hashlib模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 摘要算法 ...

随机推荐

  1. Java 发送邮件工具类

    1.  Mail.java package util; import java.util.Date; import java.util.Properties; import javax.mail.Au ...

  2. ReentrantReadWriteLock的使用

    ReentrantReadWriteLock的规则是: 多线程情况下:读-写互斥.写-读互斥.写-写互斥.读-读共享 验证“读-写互斥.写-读互斥.写-写互斥.读-读共享” //单个线程 读-读 不互 ...

  3. 干净的架构The Clean Architecture_软件架构系列

    本文转载自:https://www.jdon.com/artichect/the-clean-architecture.html ,这个博客站很有历史了,博主经常翻译Github大牛的文章,值得墙裂推 ...

  4. 在Drupal7中创建web接口

    Services 模块允许您从一个主要模块后端配置和管理区域启用您 Drupal 站点上自定义构建的内容服务器和服务.该模块中包含的服务允许您调用内容,从 Drupal 的默认和分配的 File.Co ...

  5. Tomcat:javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat异常

    问题: 在关闭tomcat时: Tomat报出一下异常:ERROR [com.alibaba.druid.stat.DruidDataSourceStatManager] – unregister m ...

  6. Java - 网络

    要事为先,你如果想要在这个行业发展下去的话,实际上三角形的三个点在支撑着你发展,一个是技术.一个是管理(不是说管理别人,是管理你自己的时间,管理你自己的精力).还有一个就是沟通,注重这三点均衡的发展. ...

  7. Cisco交换机与路由器命令总结

    1.查看信息 show version    查看版本及引导信息 show running-config     查看运行设置 show startup-config     查看开机设置 show ...

  8. php 数据脱敏显示

    /** * 数据脱敏 * @param $string 需要脱敏值 * @param int $start 开始 * @param int $length 结束 * @param string $re ...

  9. DeepFaceLab进阶(4):通过Colab免费使用Tesla K80 跑模型!

    当学会了换脸软件DeepFaceLab基本使用,各种参数配置,各有优化技能之后.唯一约束你的可能是电脑配置. CPU能跑,但是慢到怀疑人生,低配模型都得跑一周 低配显卡,显存不够,H128 根本就跑不 ...

  10. 用Python学分析 - 单因素方差分析

    单因素方差分析(One-Way Analysis of Variance) 判断控制变量是否对观测变量产生了显著影响 分析步骤 1. 建立检验假设 - H0:不同因子水平间的均值无差异 - H1:不同 ...