/** @file log.c @brief 系统日志接口文件 @details 实现本地磁盘日志和调试器控制台日志输出 @version 1.0.0 @author HuangXin @date 2012-11-20 @copyright Synway */ #include #include #include #include "log.h" #ifndef NULL #define NULL (0) #endif #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif static int g_iMinLevel = LOG_All; /** * @brief Log 调试等级转字符串 * @param level 调试等级 * @return 调试等级对应的字符串 */ static const char* LogLevelToStr(LOG_LEVEL level) { switch(level) { case LOG_Test: return "T"; case LOG_Info: return "I"; case LOG_Debug: return "D"; case LOG_Warn: return "W"; case LOG_Error: return "E"; case LOG_Fatal: return "F"; case LOG_Unknown: return "U"; default: return "U"; } return "U"; } /** * @brief 设置调试等级 * @param level 调试等级 * @param iEnable 1 打开调试等级, 0 关闭调试等级 */ void HD_EnableLogLevel(LOG_LEVEL level, int iEnable) { if(iEnable > 0) { g_iMinLevel |= level; } else { g_iMinLevel &= ~(level); } } /** * @brief 格式化 Log,添加 Log附加信息 * @details 在 Log 中加入日期时间,调试等级等附加信息 * @param cFlag 调试信息开关 * @param pMsg 调试信息内容 * @param dt Log 输出的时间 */ static void HD_LinuxPrintf(LOG_LEVEL level, struct tm* dt, const char* pMsg) { char* pDebugMsg = (char*)kmalloc(strlen(pMsg) + 64, GFP_KERNEL); if(pDebugMsg == NULL) { printk("Log Malloc Memory Error\n"); printk("%s", pMsg); return; } sprintf(pDebugMsg, "[%02d:%02d:%02d:%03d] [%s] %s", dt->tm_hour, dt->tm_min, dt->tm_sec, dt->tm_yday, LogLevelToStr(level), pMsg); printk(pDebugMsg); kfree(pDebugMsg); } /** * @brief 输出调试信息 * @details 根据 \a cFlag 的等级输出调试信息 \a pMsg * @param cFlag 调试信息开关 * @param pMsg 调试信息内容 */ static void HD_PRINTF(LOG_LEVEL level, const char* pMsg) { struct timeval tv; struct tm wtm; do_gettimeofday(&tv); time_to_tm(tv.tv_sec, 0, &wtm); wtm.tm_yday = tv.tv_usec / 1000; HD_LinuxPrintf(level, &wtm, pMsg); } /** * @brief 输出调试信息 * @param cFlag 调试信息开关 * @param pMsg 调试信息内容 */ void HD_LOG(LOG_LEVEL level, const char* pMsg, ...) { __builtin_va_list arg_ptr; int iMsgLen = 0; char buf[512]; char* pMsgBuf = NULL; // 检查调试等级 if(!(g_iMinLevel & level)) { return; } memset(buf, 0, sizeof(buf)); va_start(arg_ptr, pMsg); iMsgLen = __builtin_vsnprintf(buf, sizeof(buf), pMsg, arg_ptr); va_end(arg_ptr); if(iMsgLen > sizeof(buf)) { pMsgBuf = (char*)kmalloc(iMsgLen + 1, GFP_KERNEL); if(pMsgBuf == NULL) { return; } va_start(arg_ptr, pMsg); iMsgLen = __builtin_vsnprintf(pMsgBuf, iMsgLen + 1, pMsg, arg_ptr); va_end(arg_ptr); HD_PRINTF(level, pMsgBuf); kfree(pMsgBuf); } else { HD_PRINTF(level, buf); } }