1. Log机制
做一些大型项目的时候,对代码的调试最有效的办法往往是最直接、最简单的log机制:
即对可以出设置打印店,对应打印信息进行调试(当然是有gdb也许你会觉得很高大上,但是实际项目中,gdb比较繁琐,且比较适合老司机使用)。
如果log机制打印的好,则会事半功倍,大大提升调试的效率。博主今天就工作当中的使用到的log机制分享给大家,希望对大家有所帮助。
先看几张图:
1). Trace:
格式: 日期+时间+文件名+ <函数名 所在行> + : + 打印的信息
2). Error Log:
格式: Time + 设备信息 + 系统信息 + 系统事件编号 + 错误信息
2. Trace code
/* 功能描述: 获取当前系统日期,并转化成字符串输出 */
int get_date_string(char *str)
{
time_t now;
struct tm *tm_now;
time(&now);
tm_now = localtime(&now);
sprintf(str,"%4d-%02d-%02d %02d:%02d:%02d",
tm_now->tm_year+1900, tm_now->tm_mon+1, tm_now->tm_mday,
tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);
return 0;
}
/* 功能描述: 获取当前系统时间,返回值单位为微妙 */
uint64_t get_sys_time_usec()
{
timeval tv;
gettimeofday(&tv,NULL);
return (tv.tv_usec);
}
/******************************************************************************
*宏定义: Trace_Log
*功能描述: 将中间过程信息打印到文件中
*全局影响:
*说明:必须使用宏,否则打印的函数名、行号为本函数的
* 作者: 修改时间 内容
* Jimmy 2018-03-22 创建
*
*
******************************************************************************/
#define Trace_Log(fd, fmt, arg...)
{
int err_code = 0;
char time_str[128]; /* 存储本地时间信息<年月日时分秒> */
char code_info[128]; /* 存储调用的<文件-函数-行号> */
char str[1024]; /* 存储传入的参数*/
char usec_str[32]; /*存放微秒*/
/* 1. 检查输入参数是否合法 */
if(fd < 0)
{
printf("Input arguments [fd=%d] error! ", fd);
err_code = -1;
}
if(0 == err_code)
{
memset(time_str, ' ', sizeof(time_str));
memset(code_info, ' ', sizeof(code_info));
memset(str, ' ', sizeof(str));
memset(usec_str, ' ', sizeof(usec_str));
/* 2. 获取系统时间,获取调用者的文件/函数/行号 */
get_date_string(time_str);
sprintf(usec_str, "+%06dus", get_sys_time_usec());
sprintf(code_info, ": %-10s <%-10s %u> : ", __FILE__, __FUNCTION__, __LINE__);
strcat(time_str, usec_str);
strcat(time_str, code_info); /*将两者结合*/
sprintf(str, fmt, ##arg); /*将传入的参数按格式写入到buf*/
/* 3. 将本地时间 - 文件/函数/行信息 - 字符串信息 写入到相应的文件中*/
write(fd, (void *)time_str, strlen(time_str));
usleep(1000);
write(fd, (void *)str, strlen(str));
usleep(1000);
write(fd, "
", 1);
}
}
3. Error Log code
/******************************************************************************
*宏定义: Error_Log
*功能描述: 将错误信息打印到文件中
*说明:必须使用宏,否则打印的函数名、行号为本函数的
* 作者: 修改时间 内容
* Jimmy 2018-03-28 创建
*
*
******************************************************************************/
#define Error_Log(fmt, arg...)
{
char tmp[64];
char time_str[128]; /* 存储本地时间信息<年月日时分秒> */
char code_info[64]; /* 存储调用的<文件-函数-行号> */
char usec_str[12]; /*存储微妙时间*/
char error_info[512]; /*存储错误信息*/
char dev_id[15]; /*存储设备的ID信息*/
char systemVer[8]; /*存储系统的版本号*/
char process[8]; /*存储运行软件的版本号*/
char stm32Ver[8]; /*存储底层硬件的版本号*/
if(g_err_fd != -1)
{
memset(time_str, ' ', sizeof(time_str));
memset(code_info, ' ', sizeof(code_info));
memset(usec_str, ' ', sizeof(usec_str));
memset(dev_id, ' ', sizeof(dev_id));
memset(systemVer, ' ', sizeof(systemVer));
memset(process, ' ', sizeof(process));
memset(stm32Ver, ' ', sizeof(stm32Ver));
memset(error_info, ' ', sizeof(error_info));
memset(tmp, ' ', sizeof(tmp));
/* 1. 获取时间值 */
get_date_string(time_str);
sprintf(usec_str, "+%06dus", (get_sys_time_usec()%1000000LLU));
strcat(time_str, usec_str);
write(g_err_fd, "
TIME : ", strlen("
TIME : "));
write(g_err_fd, (void *)time_str, strlen(time_str));
write(g_err_fd, "
", 1);
/* 2. 获取设备id和软件版本信息 (这些根据实际项目修改*/
GetSysCmdInfo(dev_id, "read_misc mid | tr -d '
'");
GetSysCmdInfo(systemVer, "read_misc version | tr -d '
'");
GetSysCmdInfo(process, "read_misc software_version | tr -d '
'");
GetSysCmdInfo(stm32Ver, "read_misc stm32_version | tr -d '
'");
write(g_err_fd, "DEVICE_ID : ", strlen("DEVICE_ID : "));
write(g_err_fd, (void *)dev_id, strlen(dev_id));
write(g_err_fd, "
", 1);
write(g_err_fd, "SYSTEM_VERSION : ", strlen("SYSTEM_VERSION : "));
write(g_err_fd, (void *)systemVer, strlen(systemVer));
write(g_err_fd, "
", 1);
write(g_err_fd, "PROCESS : ", strlen("PROCESS : "));
write(g_err_fd, (void *)process, strlen(process));
write(g_err_fd, "
", 1);
write(g_err_fd, "SYSTEM_EVENT : ", strlen("SYSTEM_EVENT : "));
write(g_err_fd, (void *)stm32Ver, strlen(stm32Ver));
write(g_err_fd, "
", 1);
/* 3. 获取文件的行列信息 */
sprintf(code_info, "FILE : %-10s <%-10s %u> :
", __FILE__, __FUNCTION__, __LINE__);
write(g_err_fd, (void *)code_info, strlen(code_info));
/* 4. 获取出错信息*/
sprintf(error_info, fmt, ##arg);
write(g_err_fd, "ERROR_DETAIL : " , strlen("ERROR_DETAIL : " ));
write(g_err_fd, (void *)error_info, strlen(error_info));
write(g_err_fd, "
", 1);
/* 5. 写入结束信息 */
for(int i=0; i < sizeof(tmp)-1; i++)
{tmp[i]='-';}
tmp[sizeof(tmp)-1] = ' ';
write(g_err_fd, (void *)tmp, strlen(tmp));
write(g_err_fd, "
", 1);
bzero(tmp, sizeof(tmp));
}
else
{
printf("The g_err_fd was not inited !!!");
}
}