Trace & Error log in file
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, '\0', sizeof(time_str)); \
memset(code_info, '\0', sizeof(code_info)); \
memset(str, '\0', sizeof(str)); \
memset(usec_str, '\0', 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, "\n", 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, '\0', sizeof(time_str)); \
memset(code_info, '\0', sizeof(code_info)); \
memset(usec_str, '\0', sizeof(usec_str)); \
\
memset(dev_id, '\0', sizeof(dev_id)); \
memset(systemVer, '\0', sizeof(systemVer)); \
memset(process, '\0', sizeof(process)); \
memset(stm32Ver, '\0', sizeof(stm32Ver)); \
\
memset(error_info, '\0', sizeof(error_info)); \
memset(tmp, '\0', 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, "\nTIME\t\t\t\t: ", strlen("\nTIME\t\t\t\t: ")); \
write(g_err_fd, (void *)time_str, strlen(time_str)); \
write(g_err_fd, "\n", 1); \
\
/* 2. 获取设备id和软件版本信息 (这些根据实际项目修改*/ \
GetSysCmdInfo(dev_id, "read_misc mid | tr -d '\n'"); \
GetSysCmdInfo(systemVer, "read_misc version | tr -d '\n'"); \
GetSysCmdInfo(process, "read_misc software_version | tr -d '\n'"); \
GetSysCmdInfo(stm32Ver, "read_misc stm32_version | tr -d '\n'"); \
\
write(g_err_fd, "DEVICE_ID\t\t\t: ", strlen("DEVICE_ID\t\t\t: ")); \
write(g_err_fd, (void *)dev_id, strlen(dev_id)); \
write(g_err_fd, "\n", 1); \
\
write(g_err_fd, "SYSTEM_VERSION\t\t: ", strlen("SYSTEM_VERSION\t\t: "));\
write(g_err_fd, (void *)systemVer, strlen(systemVer)); \
write(g_err_fd, "\n", 1); \
\
write(g_err_fd, "PROCESS\t\t\t: ", strlen("PROCESS\t\t: "));\
write(g_err_fd, (void *)process, strlen(process)); \
write(g_err_fd, "\n", 1); \
\
write(g_err_fd, "SYSTEM_EVENT\t\t: ", strlen("SYSTEM_EVENT\t\t: ")); \
write(g_err_fd, (void *)stm32Ver, strlen(stm32Ver)); \
write(g_err_fd, "\n", 1); \
\
/* 3. 获取文件的行列信息 */ \
sprintf(code_info, "FILE\t\t\t\t: %-10s <%-10s %u> : \n", __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\t\t: " , strlen("ERROR_DETAIL\t\t: " )); \
write(g_err_fd, (void *)error_info, strlen(error_info)); \
write(g_err_fd, "\n", 1); \
\
/* 5. 写入结束信息 */ \
for(int i=0; i < sizeof(tmp)-1; i++) \
{tmp[i]='-';} \
tmp[sizeof(tmp)-1] = '\0'; \
write(g_err_fd, (void *)tmp, strlen(tmp)); \
write(g_err_fd, "\n", 1); \
bzero(tmp, sizeof(tmp)); \
} \
\
else \
{ \
printf("The g_err_fd was not inited !!!"); \
} \
}
Trace & Error log in file的更多相关文章
- MYSQL 5.7 无法启动(Could not open error log file errno 2)
前两天电脑中毒, 病毒好像把mysql的 log.err 文件给删掉了.然后服务一直启动不了:Could not open error log file errno 2. 然后疯狂百度,搜索的结果大多 ...
- mariadb:InnoDB: Error: log file ./ib_logfile0 is of different size 0 5242880 bytes
mariadb 启动中 InnoDB: Error: log file ./ib_logfile0 is of different size 0 起因:线上正在运行的系统,因为需要调整性能,变更了my ...
- Nginx启动报错: could not open error log file: open() &q
启动nginx报如下错误: nginx: [alert] could not open error log file: open() "/usr/local/nginx/logs/error ...
- 报错问题:InnoDB: Error: log file ./ib_logfile0 is of different size
InnoDB: Error: log file ./ib_logfile0 is of different size bytesInnoDB: than specified in the .cnf f ...
- E/Trace: error opening trace file: No such file or directory
E/Trace: error opening trace file: No such file or directory (2) 有这一个错误,想了一下,然后发现是 AdroidManifest.xm ...
- The server instance Witness rejected configure request; read its error log file for more information. The reason 1427, and state 31, can be of use for
数据库服务器做了镜像之后,发现有错误信息 The server instance Witness rejected configure request; read its error log file ...
- Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'系列一:
从库报这个错误:Got fatal error 1236 from master when reading data from binary log: 'Could not find first lo ...
- mysql从库Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'报错处理
年后回来查看mysql运行状况与备份情况,登录mysql从库查看主从同步状态 mysql> show slave status\G; *************************** . ...
- Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
setup slave from backup i got error Got fatal error 1236 from master when reading data from binary l ...
随机推荐
- AngularJS 事件广播与接收 $broadcast,$emit,$on 作用域间通信 封装factory服务 发布订阅
不同作用域之间通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信. 一.说明 1.广播 $broadcast 说明:将事件从父级作用域传播至本作用域及子级作用域. 格式:$b ...
- JavaScript中的工厂函数
所谓工厂函数,就是指这些内建函数都是类对象,当你调用他们时,实际上是创建了一个类实例. 在学习jQuery的时候,我们经常会看到“工厂函数”这个概念,那么究竟什么是“工厂函数”呢?我们来看看概念,“所 ...
- 用XPath查找HTML节点或元素
更新版以后会在我的新博客更新,请您移步 https://blog.clso.fun/posts/2019-03-03/46.html 虽然JQ和JS都能很方便的查找包含了ID及类名的元素,但某些情况下 ...
- Windows下安装配置爬虫工具Scrapy及爬虫环境
爬虫工具Scrapy在Mac和Linux环境下都相对好装,但是在Windows上总会碰到各种莫名其妙的问题.本文记录下Scrapy在Window上的安装过程. 本文是基于Python2.7及Windo ...
- " XSS易容术---bypass之编码混淆篇+辅助脚本编写"
一.前言本文原创作者:vk,本文属i春秋原创奖励计划,未经许可禁止转载!很多人对于XSS的了解不深.一提起来就是:“哦,弹窗的”.”哦,偷cookie的.”骚年,你根本不知道什么是力量.虽然我也不知道 ...
- 【Anaconda】:科学计算的Python发行版
[背景] Python易用,但包管理和Python不同版本的问题比较头疼,特别是当你使用Windows的时候.为了解决这些问题,有不少发行版的Python,比如WinPython.Anaconda等, ...
- JS脚本实现CSDN免登陆免关闭广告插件自动展开“阅读更多”内容
最近在CSDN查资料,总是弹出以下弹窗,然后就自动跳转到登录页面,蛋疼! 于是重新捣腾了一下,修改了原来的脚本,最新的脚本代码如下: 温馨提示:在打开CSDN页面后立刻执行以下脚本即可免登陆免关闭广告 ...
- POJ 2572
#include<stdio.h> #include<iostream> #include<string> using namespace std; int mai ...
- 【原创】关于程序卸载的一个Bug
今天解决了一个问题,程序安装目录下的某个文件不能被卸载,干净环境下不能重现,某些计算机可以重现. 解决: 这个问题里有两个文件不能被卸载 1.由程序生成的文件,如日志,即不是通过安装包安装的文件在卸载 ...
- Java语言基础(方法与数组)_DAY05
1:函数(掌握) (1)定义在类中,有特定功能的一段小程序,可以独立运行. (2)函数的格式: 修饰符 返回值类型 函数名(形参类型 形式参数1,形参类型 形式参数2...) ...