模块(二)——简单的log日志
简单的log日志
鉴于任何功能模块或系统在调试时都需要日志打印,这里随便写了一下,作为以后代码调试之用,只实现了不同等级的日志输出功能,其他的调试功能以后再行添加;使用方法简单,只需要在头文件里事先按照log的输出等级定义几个宏即可,然后就可以在源码文件中直接使用了,后面附上使用例程;
源码如下:
LogC.h
- #ifndef __LOG_SYSTEM_H__
- #define __LOG_SYSTEM_H__
- #include <inttypes.h>
- /** 错误码基数 **/
- #define ErrorCode_Base 100
- /** 模块列表大小 **/
- #define MODULE_LIST_SIZE 32
- /**
- * Date & Time output:
- 0: no output
- 1: output date
- 2: output time
- 3: output date&time
- **/
- #define OUTPUTFlag_DateTime 3
- /**
- * MachineInfo output:
- 0: no output
- 1: output mac
- 2: output ip
- 3: output mac&ip
- **/
- #define OUTPUTFlag_MachineInfo 2
- /**
- * Version output:
- 0: no version output
- 1: output Major_Version_Number
- 2: output Minor_Version_Number
- 4: output Revision_Number[Build_Number]
- 8: output currentModule_Version_Number
- 3: output Major_Version_Number & Minor_Version_Number
- 7: output Major_Version_Number & Minor_Version_Number & Revision_Number[Build_Number]
- 15: output all
- **/
- #define OUTPUTFlag_Version 15
- /**
- * ModuleName output:
- 0: no output
- 1: output CurrentModule_Name
- **/
- #define OUTPUTFlag_ModuleName 1
- /***
- * LogLevel:
- * "Assert" : 0
- * "Fatal!" : 1
- * "Error!" : 2
- * "Warning" : 3
- * "Info" : 4
- * "Verbose : 5
- * "Debug" : 6
- * "Undefined" : default
- ***/
- #define LogFatal(moduleNO, level, args...) \
- do { \
- if (level >= LOG_LEVEL_Fatal) \
- logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Fatal, args); \
- } while(0)
- #define LogError(moduleNO, level, args...) \
- do { \
- if (level >= LOG_LEVEL_Error) \
- logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Error, args); \
- } while(0)
- #define LogWarning(moduleNO, level, args...) \
- do { \
- if (level >= LOG_LEVEL_Warning) \
- logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Warning, args); \
- } while(0)
- #define LogInfo(moduleNO, level, args...) \
- do { \
- if (level >= LOG_LEVEL_Info)\
- logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Info, args); \
- } while(0)
- #define LogVerbose(moduleNO, level, args...) \
- do { \
- if (level >= LOG_LEVEL_Verbose) \
- logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Verbose, args); \
- } while(0)
- #define LogDebug(moduleNO, level, args...) \
- do { \
- if (level >= LOG_LEVEL_Debug) \
- logVerboseCStyle(__FILE__, __LINE__, __FUNCTION__, moduleNO, LOG_LEVEL_Debug, args); \
- } while(0)
- /**
- * 时间:年-月-日-星期几 时-分-秒-毫秒
- * 格式:
- * [month-day-year, weekday][hour:min:sec.msec]
- **/
- typedef struct DT {
- uint16_t mYear; //!< e.g. 2005
- uint8_t mMonth; //!< 1...12
- uint8_t mDayOfWeek; //!< 0...6, 0==Sunday
- uint8_t mDay; //!< 1...31
- uint8_t mHour; //!< 0...23
- uint8_t mMinute; //!< 0...59
- uint8_t mSecond; //!< 0...59
- uint32_t muSecond; //!< 0...999999
- } DateTime;
- /**
- * 版本号: Major . Minor . BuildVersion : currentModuleVersion
- * Major : 主版本号
- * Minor : 子版本号
- * BuildVersion : 修正版本号 或 编译版本号
- **/
- typedef struct _Version {
- int Major; // 主版本号
- int Minor; // 子版本号
- int BuildVersion; // 编译版本号 或者 修正版本号
- } Version_t;
- /**
- * 日志类型:
- * 针对某一模块,设置日志种类;
- **/
- typedef enum _LogType {
- LogType_SYSTEM = 0x01, /** 系统相关日志 **/
- LogType_SECURITY = 0x02, /** 安全相关日志 **/
- LogType_RUNNING = 0x04, /** 运行时日志 **/
- LogType_OPERATION = 0x08, /** 操作型日志 **/
- LogType_ALL = LogType_OPERATION | LogType_RUNNING | LogType_SECURITY | LogType_SYSTEM /** 所有类型日志 **/
- }LogType;
- /**
- * 模块列表:
- * 模块名 . 模块日志等级 . 模块日志类型
- ***/
- typedef struct moduleInfo{
- char name[12];
- char version[8];
- LogType logType;
- } ModuleInfo_t;
- /**
- * 在代码中使用了不同等级的log输出宏函数,要控制日至输出的多少,只需要设置logLevel的等级即可;
- * 等级越高(或者说是值越大),可输出的log越多,举例:
- * 当logLevel设置为 LOG_LEVEL_INFO ,即 level = 3 时,在代码中设置的 level = 4(或是使用
- * MODULE_LOG_VERBOSE()宏函数)的打印日志不能输出,设置为 level <= 3(或是使用MODULE_LOG_ERROR(),
- * MODULE_LOG_WARNING(),MODULE_LOG()宏函数)的日志都可以输出;
- * 详细说明参考以下代码;
- **/
- enum LogLevel {
- LOG_LEVEL_Assert = 0x00, /** for pre-compile print log **/
- LOG_LEVEL_Fatal = 0x01,
- LOG_LEVEL_Error = 0x02, /** **/
- LOG_LEVEL_Warning = 0x03, /** **/
- LOG_LEVEL_Info = 0x04, /** **/
- LOG_LEVEL_Verbose = 0x05, /** **/
- LOG_LEVEL_Debug = 0x06,
- LOG_LEVEL_Undefined
- };
- #ifdef __cplusplus
- extern "C" {
- #endif
- /***
- * 注册模块到 g_moduleList
- * 返回 当前模块在g_moduleList列表中的位置
- * g_moduleCount表示当前注册拥有的module数量
- **/
- int registerModule(char* name, char* version, int logtype);
- /***
- 输出格式:
- [month-day-year, weekday][hour:min:sec.msec] [HostMac][HostName][Major.Minor.BuildVersion:ModuleVersion] [Module][file:line][function:log_level] : logBuffer_info.
- ***/
- void logVerboseCStyle(const char* file, int line, const char* function, int module, int level, const char* fmt, ...);
- #ifdef __cplusplus
- }
- #endif
- #endif
LogC.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <time.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <netinet/if_ether.h>
- #include <net/if.h>
- #include <linux/sockios.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #include "LogC.h"
- /**
- LogLevel: "Assert", "Fatal!", "Error!", "Warning", "Info", "Verbose", "Debug", "Undefined"
- 无 1 1 3 4 2 2 无
- 转义序列相关的常用参数如下(通过man console_codes命令可查看更多的参数描述):
- 显示:0(默认)、1(粗体/高亮)、22(非粗体)、4(单条下划线)、24(无下划线)、5(闪烁)、25(无闪烁)、7(反显、翻转前景色和背景色)、27(无反显)
- 颜色:0(黑)、1(红)、2(绿)、 3(黄)、4(蓝)、5(洋红)、6(青)、7(白)
- 前景色为30+颜色值,如31表示前景色为红色;背景色为40+颜色值,如41表示背景色为红色。
- **/
- static const uint8_t color[] = {0, 0x41, 0x41, 0x43, 0x04, 0x02, 0x02, 0x02};
- #define setLogColor(x) \
- { \
- if(x < 4) \
- fprintf(stderr, "\033[1;%d;3%dm", color[x]>>4, color[x]&15); \
- else \
- fprintf(stderr, "\033[%d;3%dm", color[x]>>4, color[x]&15); \
- }
- #define resetLogColor() fprintf(stderr, "\033[0m")
- /** 日志level名称 **/
- static const char *textLogLevel[] = {"Assert", "Fatal!", "Error!", "Warning", "Info", "Verbose", "Debug", "Undefined"};
- /** 日期字符串:月份 & 星期 **/
- static const char *monthStr[] = {"Reserved", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Undefined"};
- static const char *weekStr[] = {"Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat.", "Undefined"};
- /**
- * 用于保存模块的列表: 列表大小MODULE_LIST_SIZE指定;
- * g_moduleCount 用于记录下次添加模块是的起始位置
- **/
- static struct moduleInfo g_moduleList[MODULE_LIST_SIZE] = {};
- static int g_moduleCount = 0;
- /** g_version 使用——Version结构记录全局的版本号 **/
- struct _Version g_version;
- /**
- * 获取当前时间:年-月-日-星期几 时-分-秒-毫秒
- * 输出格式:
- * [month-day-year, weekday][hour:min:sec.msec]
- * flag: 0: no output
- 1: output date
- 2: output time
- 3: output date&time
- **/
- static int get_CurrentTime(char *buf, int flag)
- {
- if (flag == 0)
- return 0;
- static DateTime sDTime;
- struct timeval current;
- struct tm tempTime;
- if (!gettimeofday(¤t, NULL)) {
- localtime_r(¤t.tv_sec, &tempTime);
- sDTime.mYear = tempTime.tm_year + 1900;
- sDTime.mMonth = tempTime.tm_mon + 1;
- sDTime.mDayOfWeek = tempTime.tm_wday;
- sDTime.mDay = tempTime.tm_mday;
- sDTime.mHour = tempTime.tm_hour;
- sDTime.mMinute = tempTime.tm_min;
- sDTime.mSecond = tempTime.tm_sec;
- sDTime.muSecond = current.tv_usec;
- }
- if (flag & 0x01)
- sprintf(buf, "[%s-%02d-%04d, %s]", monthStr[sDTime.mMonth], sDTime.mDay, sDTime.mYear, weekStr[sDTime.mDayOfWeek]);
- if (flag & 0x02)
- sprintf(buf + strlen(buf), "[%02d:%02d:%02d.%03d] ", sDTime.mHour, sDTime.mMinute, sDTime.mSecond, sDTime.muSecond / 1000);
- //printf("get_CurrentTime: buf[%s]...\n", buf);
- return strlen(buf);
- }
- /**
- * 获取设备信息: mac,hostname,ip,串号等
- * flag: 0: no output
- 1: output mac
- 2: output ip
- 3: output mac&ip
- **/
- static int get_MachineInfo(const char *device, char *buf, int flag)
- {
- if (flag == 0)
- return 0;
- unsigned char macAddr[6] = {0}; //6是MAC地址长度
- unsigned char ipAddr[18] = {0};
- unsigned char hostName[32] = {0};
- int sockfd;
- struct ifreq ifr4dev;
- sockfd = socket(AF_INET, SOCK_DGRAM, 0); //internet协议族的数据报类型套接口
- strncpy(ifr4dev.ifr_name, device, sizeof(ifr4dev.ifr_name) - 1); //将设备名作为输入参数传入
- //获取MAC地址
- ifr4dev.ifr_hwaddr.sa_family = ARPHRD_ETHER; //此处需要添加协议,网络所传程序没添加此项获取不了mac。
- if (ioctl(sockfd, SIOCGIFHWADDR, &ifr4dev) == -1) {
- printf("get_MachineInfo: get device [%s] mac error.\n", device);
- return -1;
- }
- memcpy(macAddr, ifr4dev.ifr_hwaddr.sa_data, ETH_ALEN);
- //获取ip地址
- if (ioctl(sockfd, SIOCGIFADDR, &ifr4dev) == -1) {
- printf("get_MachineInfo: get device [%s] ip error.\n", device);
- return -1;
- }
- /**
- struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,
- 二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
- 一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。
- **/
- struct sockaddr_in *sin = (struct sockaddr_in *)&ifr4dev.ifr_addr;
- strcpy((char *)ipAddr, inet_ntoa(sin->sin_addr));
- close(sockfd);
- //get hostName
- gethostname((char *)hostName, sizeof(hostName));
- sprintf(buf, "[%s]", hostName);
- if (flag & 0x01)
- sprintf(buf + strlen(buf), "[%02x:%02x:%02x:%02x:%02x:%02x] ", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
- if (flag & 0x02)
- sprintf(buf + strlen(buf) - 1, "[%s] ", ipAddr);
- //printf("get_MachineInfo: mac&ip buf=[%s]\n", buf);
- return (int)strlen(buf);
- }
- /**
- * 获取版本号: Major.Minor.BuildVersion:currentModuleVersion
- 主版本号 . 子版本号 [. 修正版本号 或 编译版本号 ] : 当前模块版本号
- * flag: 0: no version output
- 1: output Major_Version_Number
- 2: output Minor_Version_Number
- 4: output Revision_Number[Build_Number]
- 8: output currentModule_Version_Number
- 3: output Major_Version_Number & Minor_Version_Number
- 7: output Major_Version_Number & Minor_Version_Number & Revision_Number[Build_Number]
- 15: output all
- *
- * 注: 需要预先将版本号填充到 _Version 结构体
- **/
- static int get_Version(char *buf, int module, int flag)
- {
- if ((flag == 0) || (flag == 5) || (flag == 6) || ((8 < flag) && (flag < 15)) || (flag > 15))
- return 0;
- char tmp_currentModuleVersion[12] = {};
- if (g_version.BuildVersion == 0) {
- g_version.Major = 0;
- g_version.Minor = 0;
- g_version.BuildVersion = 0;
- }
- sprintf(buf, "%s", "[");
- if (flag & 0x01)
- sprintf(buf + strlen(buf), "%d", g_version.Major);
- if (flag & 0x02)
- sprintf(buf + strlen(buf), ".%d", g_version.Minor);
- if (flag & 0x04)
- sprintf(buf + strlen(buf), ".%d", g_version.BuildVersion);
- if (flag & 0x08) {
- strcpy(tmp_currentModuleVersion, g_moduleList[module].version);
- sprintf(buf + strlen(buf), ":%s", tmp_currentModuleVersion);
- }
- sprintf(buf + strlen(buf), "%s", "]");
- //printf("get_Version: buf[%s]\n", buf);
- return strlen(buf);
- }
- /***
- * 注册模块到 g_moduleList 列表
- * 返回 当前模块在g_moduleList列表中的位置;
- * g_moduleCount 表示当前列表中已注册的(已拥有的)module数量;
- **/
- int registerModule(char *name, char *version, int logtype)
- {
- int k = 0;
- if (g_moduleCount < 0 || g_moduleCount >= MODULE_LIST_SIZE)
- return -1;
- strncpy((char *)&g_moduleList[g_moduleCount].name, name, 12);
- strncpy((char *)&g_moduleList[g_moduleCount].version, version, 8);
- g_moduleList[g_moduleCount].logType = logtype;
- k = g_moduleCount;
- g_moduleCount++;
- return k;
- }
- /**
- * 从模块列表中获取当前模块名:
- * flag: 0: no output
- 1: output CurrentModule_Name
- *
- * 注: 需要预先将模块注册
- **/
- static int get_CurrentModuleName(char *buf, int module, int flag)
- {
- if (flag == 0)
- return 0;
- if (module < 0 || module >= MODULE_LIST_SIZE)
- return -1;
- if (0 != strcmp(g_moduleList[module].name, "")) {
- sprintf(buf, "[%s] ", g_moduleList[module].name);
- } else {
- sprintf(buf, "[%s] ", "0000000");
- }
- //printf("get_CurrentModuleName: buf[%s]\n", buf);
- return strlen(buf);
- }
- /**
- * 计算出错误码值:
- * 计算出的 errorcode 是大于 ErrorCode_Base 的
- * 计算出的 errorcode 区间(数字从小到大): system--security--running--operation
- **/
- static int get_ErrorCode(char *buf, int module, int level)
- {
- int logtype = 0;
- int errcode = 0;
- if ((module < 0 || module >= MODULE_LIST_SIZE) || (0 == strcmp(g_moduleList[module].name, "")))
- return -1;
- logtype = g_moduleList[module].logType;
- //TODO: 根据一定规则,由logtype和loglevel计算出errorcode值;
- switch (logtype) {
- case LogType_OPERATION: /** operation type error **/
- errcode = ErrorCode_Base + LogType_OPERATION * 8 + level;
- break;
- case LogType_RUNNING: /** running type error **/
- errcode = ErrorCode_Base + LogType_RUNNING * 8 + level;
- break;
- case LogType_SECURITY: /** security type error **/
- errcode = ErrorCode_Base + LogType_SECURITY * 8 + level;
- break;
- case LogType_SYSTEM: /** system type error **/
- errcode = ErrorCode_Base + LogType_SYSTEM * 8 + level;
- break;
- case LogType_ALL: /** all type error **/
- errcode = ErrorCode_Base + LogType_ALL * 8 + level;
- break;
- default:
- printf("get_ErrorCode: logtype [%d] is error.\n", logtype);
- break;
- }
- sprintf(buf, "<<%d>> ", errcode);
- //printf("get_ErrorCode: buf[%s]\n", buf);
- return strlen(buf);
- }
- /**
- * 设置log输出颜色并输出:
- * 日志level : 颜色及输出设置:
- "Fatal!" 1(粗体/高亮)、4(单条下划线)、1(红)
- "Error!" 1(粗体/高亮)、4(单条下划线)、1(红)
- "Warning" 1(粗体/高亮)、4(单条下划线)、3(黄)
- "Info" 4(蓝)
- "Verbose" 2(绿)
- "Debug" 2(绿)
- **/
- static int useColor = -1;
- static int colored_LogOutput(int level, char *str)
- {
- if (useColor < 0) {
- useColor = !getenv("NO_COLOR") && !getenv("LOG_FORCE_NOCOLOR") && ((getenv("TERM") && isatty(1)) || getenv("LOG_FORCE_COLOR"));
- }
- if (useColor)
- setLogColor(level);
- if ((level <= LOG_LEVEL_Assert) || (level >= LOG_LEVEL_Undefined)) {
- printf("colored_LogOutput: level is [%d],error.\n", level);
- fputs(str, NULL);
- } else
- fputs(str, stdout); //输出到stdout
- if (useColor)
- resetLogColor();
- return 0;
- }
- /**
- * 净化log输出信息:
- * 可输出的字符范围: 0x08(退格)———— 0x0D(回车键); 0x20(空格)———— 0x7F(删除)
- * 其他字符均使用 ‘?’替代输出;
- **/
- static void logLineSanitize(uint8_t *str)
- {
- int k = 0;
- while (*str) {
- if (*str < 0x08 || (*str > 0x0D && *str < 0x20)) {
- *str = '?';
- k++;
- }
- str++;
- }
- return ;
- }
- /***
- 输出格式:
- [month-day-year, weekday][hour:min:sec.msec] [HostMac][HostIP] [Major.Minor.BuildVersion:ModuleVersion][ModuleName] [ErrorCode][file:line][function:LogLevel] : logBuffer_info.
- ***/
- void logVerboseCStyle(const char *file, int line, const char *function, int module, int level, const char *fmt, ...)
- {
- va_list args;
- char currTime[48] = {0};
- char machineInfo[64] = {0};
- char version[16] = {0};
- char moduleName[16] = {0};
- char errorCode[16] = {0};
- static char sLogBuffer[512] = { 0 };
- static char str[1024] = {0};
- // date & time
- get_CurrentTime((char *)&currTime, OUTPUTFlag_DateTime);
- // mac & ip
- get_MachineInfo("eth0", (char *)&machineInfo, OUTPUTFlag_MachineInfo);
- // version
- get_Version((char *)&version, module, OUTPUTFlag_Version);
- // module
- get_CurrentModuleName((char *)&moduleName, module, OUTPUTFlag_ModuleName);
- // errorcode
- get_ErrorCode((char *)&errorCode, module, level);
- va_start(args, fmt);
- vsnprintf(sLogBuffer, 512, fmt, args);
- va_end(args);
- snprintf(str, strlen(currTime) + 1, "%s", currTime);
- snprintf(str + strlen(str), strlen(machineInfo) + 1, "%s", machineInfo);
- snprintf(str + strlen(str), strlen(version) + 1, "%s", version);
- snprintf(str + strlen(str), strlen(moduleName) + 1, "%s", moduleName);
- snprintf(str + strlen(str), strlen(errorCode) + 1, "%s", errorCode);
- sprintf(str + strlen(str), "[%s:%d][%s:%s] ", (strchr(file, '/') ? (strchr(file, '/') + 1) : file), line, function, textLogLevel[level]);
- sprintf(str + strlen(str), ": %s", sLogBuffer);
- logLineSanitize((uint8_t *)str);
- colored_LogOutput(level, str);
- return ;
- }
简单的功能测试代码:
用于测试的源文件 logTest.c
- #include <stdio.h>
- #include "LogC.h"
- #include "test/upgrade.h"
- #include "test/example.h"
- extern struct _Version g_version;
- int log_init()
- {
- //register to module list
- g_moduleUpgradeNO = registerModule(ModuleName_UPGRADE, ModuleVersion_UPGRADE, ModuleLogType_UPGRADE);
- g_moduleBuildNO = registerModule(ModuleName_BUILD, ModuleVersion_BUILD, ModuleLogType_BUILD);
- return 0;
- }
- int main()
- {
- //init g_version
- g_version.Major = 9;
- g_version.Minor = 88;
- g_version.BuildVersion = 777;
- log_init();
- upgradeLogFatal("=====upgradeLogFatal==[%d]=--------------=\n", g_moduleUpgradeNO);
- upgradeLogError("=====upgradeLogError==[%d]=--------------=\n", g_moduleUpgradeNO);
- upgradeLogWarning("=====upgradeLogWarning==[%d]=--------------=\n", g_moduleUpgradeNO);
- upgradeLogInfo("=====upgradeLogInfo==[%d]=--------------=\n", g_moduleUpgradeNO);
- upgradeLogVerbose("=====upgradeLogVerbose==[%d]=--------------=\n", g_moduleUpgradeNO);
- upgradeLogDebug("=====upgradeLogDebug==[%d]=--------------=\n", g_moduleUpgradeNO);
- printf("==========================================\n");
- buildLogFatal("=====buildLogFatal==[%d]=--------------=\n", g_moduleBuildNO);
- buildLogError("=====buildLogError==[%d]=--------------=\n", g_moduleBuildNO);
- buildLogWarning("=====buildLogWarning==[%d]=--------------=\n", g_moduleBuildNO);
- buildLogInfo("=====buildLogInfo==[%d]=--------------=\n", g_moduleBuildNO);
- buildLogVerbose("=====buildLogVerbose==[%d]=--------------=\n", g_moduleBuildNO);
- buildLogDebug("=====buildLogDebug==[%d]=--------------=\n", g_moduleBuildNO);
- return 0;
- }
事先按log等级定义好宏的头文件 example.h
- #ifndef __BUILD_H__
- #define __BUILD_H__
- #include "LogC.h"
- #define ModuleName_BUILD "build"
- #define ModuleVersion_BUILD "45343"
- #define ModuleLogType_BUILD LogType_ALL
- /**
- * g_moduleBuildNO: 记录当前模块在模块列表中的位置
- * g_buildLogLevel: 设置当前模块的log输出等级,每个模块都可设置独立的log输出等级
- **/
- int g_moduleBuildNO = 0;
- static int g_buildLogLevel = LOG_LEVEL_Debug;
- #define buildLogFatal(args...) LogFatal(g_moduleBuildNO, g_buildLogLevel, args)
- #define buildLogError(args...) LogError(g_moduleBuildNO, g_buildLogLevel, args)
- #define buildLogWarning(args...) LogWarning(g_moduleBuildNO, g_buildLogLevel, args)
- #define buildLogInfo(args...) LogInfo(g_moduleBuildNO, g_buildLogLevel, args)
- #define buildLogVerbose(args...) LogVerbose(g_moduleBuildNO, g_buildLogLevel, args)
- #define buildLogDebug(args...) LogDebug(g_moduleBuildNO, g_buildLogLevel, args)
- #endif
还有一个 upgrade.h
- #ifndef __UPGRADE_H__
- #define __UPGRADE_H__
- #include "LogC.h"
- #define ModuleName_UPGRADE "upgrade"
- #define ModuleVersion_UPGRADE "1111"
- #define ModuleLogType_UPGRADE LogType_SECURITY
- /**
- * g_moduleUpgradeNO: 记录当前模块在模块列表中的位置
- * g_upgradeLogLevel: 设置当前模块的log输出等级,每个模块都可设置独立的log输出等级
- **/
- int g_moduleUpgradeNO = 0;
- static int g_upgradeLogLevel = LOG_LEVEL_Debug;
- #define upgradeLogFatal(args...) LogFatal(g_moduleUpgradeNO, g_upgradeLogLevel, args)
- #define upgradeLogError(args...) LogError(g_moduleUpgradeNO, g_upgradeLogLevel, args)
- #define upgradeLogWarning(args...) LogWarning(g_moduleUpgradeNO, g_upgradeLogLevel, args)
- #define upgradeLogInfo(args...) LogInfo(g_moduleUpgradeNO, g_upgradeLogLevel, args)
- #define upgradeLogVerbose(args...) LogVerbose(g_moduleUpgradeNO, g_upgradeLogLevel, args)
- #define upgradeLogDebug(args...) LogDebug(g_moduleUpgradeNO, g_upgradeLogLevel, args)
- #endif
模块(二)——简单的log日志的更多相关文章
- C++简单实现Log日志类轻量级支持格式化输出变量
CLog 头 代码很简单 如果需要的直接Ctrl+C ----Ctrl+V 即可 #ifndef __CLOG__ #define __CLOG__ #include <windows.h&g ...
- Py修行路 python基础 (二十一)logging日志模块 json序列化 正则表达式(re)
一.日志模块 两种配置方式:1.config函数 2.logger #1.config函数 不能输出到屏幕 #2.logger对象 (获取别人的信息,需要两个数据流:文件流和屏幕流需要将数据从两个数据 ...
- python的logging日志模块(二)
晚上比较懒,直接搬砖了. 1.简单的将日志打印到屏幕 import logging logging.debug('This is debug message') logging.info('Thi ...
- 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块
Log4a 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块 github地址 : https://github.com/EalenXie/log4a 在API每次被请求时 ...
- 韦大仙--简单的monkey测试命令行操作及生成log日志保存
作中,在将apk交给软件测试人员去测试之前,不免要自己先自测,monkey自测是一个不错的选择! 步骤很简单: 1.测试用的手机与电脑连接好USB ,并且安装好驱动(我一般都是通过豌豆荚自动安装的)! ...
- python之log日志模块
logging的配置大致有下面几种方式. 1. 通过代码进行完整配置,logging.getLogger()获取logger后,给logger设置各种handler. 2. ...
- java最简单实现Log打印和生成日志文件
导包 1.commons-logging.jar包 下载 2.log4j.jar包 下载 配置log4j 1.在src根目录下创建一个log4j.properties文件. 文件全部内容如下: log ...
- BIND的进阶二:视图,日志,转发,子域的授权
实验分为4部分组成: 1:DNS的转发 2:DNS日志 3:子域的授权 4:智能DNS的简单配置根据网段来分配不同的ip地址 一:DNS的转发: 转发方式有两种:only (直接把客户端请 ...
- python之常用模块二(hashlib logging configparser)
摘要:hashlib ***** logging ***** configparser * 一.hashlib模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 摘要算法 ...
随机推荐
- Java 发送邮件工具类
1. Mail.java package util; import java.util.Date; import java.util.Properties; import javax.mail.Au ...
- ReentrantReadWriteLock的使用
ReentrantReadWriteLock的规则是: 多线程情况下:读-写互斥.写-读互斥.写-写互斥.读-读共享 验证“读-写互斥.写-读互斥.写-写互斥.读-读共享” //单个线程 读-读 不互 ...
- 干净的架构The Clean Architecture_软件架构系列
本文转载自:https://www.jdon.com/artichect/the-clean-architecture.html ,这个博客站很有历史了,博主经常翻译Github大牛的文章,值得墙裂推 ...
- 在Drupal7中创建web接口
Services 模块允许您从一个主要模块后端配置和管理区域启用您 Drupal 站点上自定义构建的内容服务器和服务.该模块中包含的服务允许您调用内容,从 Drupal 的默认和分配的 File.Co ...
- Tomcat:javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat异常
问题: 在关闭tomcat时: Tomat报出一下异常:ERROR [com.alibaba.druid.stat.DruidDataSourceStatManager] – unregister m ...
- Java - 网络
要事为先,你如果想要在这个行业发展下去的话,实际上三角形的三个点在支撑着你发展,一个是技术.一个是管理(不是说管理别人,是管理你自己的时间,管理你自己的精力).还有一个就是沟通,注重这三点均衡的发展. ...
- Cisco交换机与路由器命令总结
1.查看信息 show version 查看版本及引导信息 show running-config 查看运行设置 show startup-config 查看开机设置 show ...
- php 数据脱敏显示
/** * 数据脱敏 * @param $string 需要脱敏值 * @param int $start 开始 * @param int $length 结束 * @param string $re ...
- DeepFaceLab进阶(4):通过Colab免费使用Tesla K80 跑模型!
当学会了换脸软件DeepFaceLab基本使用,各种参数配置,各有优化技能之后.唯一约束你的可能是电脑配置. CPU能跑,但是慢到怀疑人生,低配模型都得跑一周 低配显卡,显存不够,H128 根本就跑不 ...
- 用Python学分析 - 单因素方差分析
单因素方差分析(One-Way Analysis of Variance) 判断控制变量是否对观测变量产生了显著影响 分析步骤 1. 建立检验假设 - H0:不同因子水平间的均值无差异 - H1:不同 ...