【源码分享】调试篇之制造简易日志函数
【源码分享】调试篇之打造简易日志函数
资源下载地址:http://download.****.net/detail/void998/8617989
包含内容:视频+源码
内容很简单,介绍了一个比较实用的日志函数。
支持如下:
1、多参数输入,类似CSring的Format函数那样。
2、每条日志都自动添加时间。
适合初学者学习哈。
先把函数代码贴出来
内容很简单,也比较实用,非常适合初学者学习哈!
------解决思路----------------------
仅供参考:
------解决思路----------------------
不错,适合入门。
但是离产品级的库还有相当长的一段路。
------解决思路----------------------
问题在于每输出一条日志,就open、close一次文件
------解决思路----------------------
问题在于对不是每输出一条日志,就open、close一次文件的日志系统,
停电或拔电后再重启,能保证看到最后一条写出的日志吗?
还有在其它进程读取日志文件时能保证看到最后一条写出的日志吗?
尺有所短,寸有所长。
------解决思路----------------------
编程就应该用成就感保持热情。
要做的东西还多着呢
效率
线程安全
fork支持
日志级别
日志固定大小、固定时间生成新文件
老文件固定规则收集
挂在不同后端(例如不同级别输出到不同文件设置socket上)
日志文件名方便运维管理
等等等等
------解决思路----------------------
个人意见:日志级别是鸡肋。
------解决思路----------------------
除了线程安全,日志格式,文件名
最有用就是日志级别了
------解决思路----------------------
那是因为你没被一个表面上是Warning级别而实际上是Caution级别的日志,因为设置了Error级别没输出,而将你纠正错误的时间足足延长了好几年的痛苦经历!
------解决思路----------------------
你说的这种情况恰恰说明了级别控制的重要性
很多日志信息的级别都是需要实时调整的
为什么该是更高级别的日志却好几年没被提高等级?只能说级别被你们用烂了,导致生存环境信息过多过杂无法调整
------解决思路----------------------
再说warning级别已经很重要了啊
有问题的时候warning都不开不看吗
------解决思路----------------------
楼主你要知道, 每次写日志都要打开、关闭文件一次, 那得浪费多少资源?
------解决思路----------------------
因为你脑海中还没有“每条日志的实际级别是无法预知的”这样字字血声声泪的教训。
------解决思路----------------------
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
------解决思路----------------------
哎, 老发这个有用吗?
我跟楼主说的这个不是什么算法优化, 而只是一个很浅显的道理
既然经常用到的功能我们需要给它独立写一个函数,那为什么经常用到的句柄我们就不能给它独立申明呢?
试想一下, 如果每个函数都调用楼主的日志函数, 那这个开销就不可估量了
的确现在的硬件发展很迅速, 但并不是每个客户都使用这些高端设备
小型商铺、车间电脑、一般的办公计算机等等这些在我的客户群里占了90%以上
这90%里面有起码50%用的还是单核计算机,车间用的电脑有的还是 win98
开发人员需要跟上时代的步伐这没错,但也得结合实际应用而考虑
你不可能说出了iPhone6就不去考虑iPhone4的用户
能用得上你所说这些设备的能有多少?那么在这些人里面真正会使用商业软件的人又有多少?
------解决思路----------------------
自己调试软件用的多了,觉的每个调试手段都很重要,用好调试手段,可以大大节省查找问题的时间。
------解决思路----------------------
请老实回答我,你用过哪怕一次profiler功能查看程序实际运行时的性能瓶颈在哪里吗?
Using PROFILE, PREP, and PLIST
Home
------解决思路----------------------
Overview
------解决思路----------------------
Details
Feature Only in Professional and Enterprise Editions Profiling is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
Profiling requires three separate programs: PREP, PROFILE, and PLIST. When you choose a standard option (other than Custom) from the Profile dialog box, the development environment executes these programs for you automatically, passing arguments to the PREP program.
If you want maximum profiling flexibility, including the ability to format your output and to specify function and line-count profiling, you must write your own batch files that invoke PREP, PROFILE, and PLIST. You can run these batch files from either the Profile dialog box or from the command prompt. If you run the batch file from the dialog box, the PLIST output will, by default, be routed to the output window. Command-line batch output can also be routed to a file.
The following figure illustrates the profiler batch processing flow.
Profiler Batch Processing Flow
Notice that the PREP program is called twice. Phase I is before the actual profiling and Phase II is after the profiling. The command-line arguments govern PREP’s behavior.
The .PBI, .PBO, and .PBT files are intermediate files that are used to transfer information between profiling steps. The broken lines indicate connections that depend on the PREP (Phase I) command-line options.
A typical profiler batch file might look like this:
PREP /OM /FT /EXC nafxcwd.lib %1
if errorlevel == 1 goto done
PROFILE %1 %2 %3 %4 %5 %6 %7 %8 %9
if errorlevel == 1 goto done
PREP /M %1
if errorlevel == 1 goto done
PLIST /SC %1 >%1.lst
:done
Note When you run a profiler batch file from the Profile dialog box using the Custom option, the PLIST standard output is routed to the Profile tab in the Output window. In the preceding batch file, the PLIST output is redirected to a file, as it would usually be in a batch file run from the command line.
When the batch file is run using the Custom option in the Profile dialog box, the development environment substitutes the project’s program name for the %1 parameter. You can specify your program’s command-line arguments on the Debug tab in the Project Settings dialog box.
If the preceding batch file was named FTIME.BAT, and you wanted to profile the program TEST from the Profile dialog box, you would select the Custom option, and then specify FTIME.BAT in the Custom Settings box. If you wanted to profile the TEST program from the command prompt, you would type:
FTIME TEST
Note If you are running a profiler batch file from the development environment, you can edit your batch file. Remember to save your batch files after editing, because the development environment does not save them automatically.
------解决思路----------------------
我所说的是一个编程意识
------解决思路----------------------
很多过去屡试不爽的编程意识,到现在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代早已经过时了。
资源下载地址:http://download.****.net/detail/void998/8617989
包含内容:视频+源码
内容很简单,介绍了一个比较实用的日志函数。
支持如下:
1、多参数输入,类似CSring的Format函数那样。
2、每条日志都自动添加时间。
适合初学者学习哈。
先把函数代码贴出来
void TraceLog(char* lpszFormat, ...)
{
va_list args;
char sTemp[512] = "";
va_start(args, lpszFormat);
_vsnprintf(sTemp, sizeof(sTemp), lpszFormat, args);
va_end(args);
//日期
SYSTEMTIME sysTime;
::GetLocalTime(&sysTime);
char sTrace[1024] = "";
sprintf(sTrace, "[%02u:%02u:%02u: %02u:%02u:%02u] %s\r\n"
, sysTime.wYear, sysTime.wMonth, sysTime.wDay
, sysTime.wHour, sysTime.wMinute, sysTime.wSecond
, sTemp);
//输出到文件
FILE* pFile = NULL;
pFile = fopen("C:\\TraceLog.txt", "a");
fwrite(sTrace, 1, strlen(sTrace), pFile);
fclose(pFile);
pFile = NULL;
}
内容很简单,也比较实用,非常适合初学者学习哈!
------解决思路----------------------
仅供参考:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define _vsnprintf vsnprintf
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt
------解决思路----------------------
0==pszFmt[0]) return;
_vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
int main(int argc,char * argv[]) {
int i;
#ifdef WIN32
InitializeCriticalSection(&cs_log);
#else
pthread_mutex_init(&cs_log,NULL);
#endif
for (i=0;i<10000;i++) {
Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);
}
#ifdef WIN32
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}
//1-78行添加到你带main的.c或.cpp的那个文件的最前面
//81-85行添加到你的main函数开头
//89-93行添加到你的main函数结束前
//在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中
------解决思路----------------------
不错,适合入门。
但是离产品级的库还有相当长的一段路。
------解决思路----------------------
问题在于每输出一条日志,就open、close一次文件
------解决思路----------------------
问题在于对不是每输出一条日志,就open、close一次文件的日志系统,
停电或拔电后再重启,能保证看到最后一条写出的日志吗?
还有在其它进程读取日志文件时能保证看到最后一条写出的日志吗?
尺有所短,寸有所长。
------解决思路----------------------
编程就应该用成就感保持热情。
要做的东西还多着呢
效率
线程安全
fork支持
日志级别
日志固定大小、固定时间生成新文件
老文件固定规则收集
挂在不同后端(例如不同级别输出到不同文件设置socket上)
日志文件名方便运维管理
等等等等
------解决思路----------------------
个人意见:日志级别是鸡肋。
------解决思路----------------------
除了线程安全,日志格式,文件名
最有用就是日志级别了
------解决思路----------------------
------解决思路----------------------
你说的这种情况恰恰说明了级别控制的重要性
很多日志信息的级别都是需要实时调整的
为什么该是更高级别的日志却好几年没被提高等级?只能说级别被你们用烂了,导致生存环境信息过多过杂无法调整
------解决思路----------------------
再说warning级别已经很重要了啊
有问题的时候warning都不开不看吗
------解决思路----------------------
楼主你要知道, 每次写日志都要打开、关闭文件一次, 那得浪费多少资源?
------解决思路----------------------
因为你脑海中还没有“每条日志的实际级别是无法预知的”这样字字血声声泪的教训。
------解决思路----------------------
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
------解决思路----------------------
哎, 老发这个有用吗?
我跟楼主说的这个不是什么算法优化, 而只是一个很浅显的道理
既然经常用到的功能我们需要给它独立写一个函数,那为什么经常用到的句柄我们就不能给它独立申明呢?
试想一下, 如果每个函数都调用楼主的日志函数, 那这个开销就不可估量了
的确现在的硬件发展很迅速, 但并不是每个客户都使用这些高端设备
小型商铺、车间电脑、一般的办公计算机等等这些在我的客户群里占了90%以上
这90%里面有起码50%用的还是单核计算机,车间用的电脑有的还是 win98
开发人员需要跟上时代的步伐这没错,但也得结合实际应用而考虑
你不可能说出了iPhone6就不去考虑iPhone4的用户
能用得上你所说这些设备的能有多少?那么在这些人里面真正会使用商业软件的人又有多少?
------解决思路----------------------
自己调试软件用的多了,觉的每个调试手段都很重要,用好调试手段,可以大大节省查找问题的时间。
------解决思路----------------------
楼主你要知道, 每次写日志都要打开、关闭文件一次, 那得浪费多少资源?
无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
哎, 老发这个有用吗?
我跟楼主说的这个不是什么算法优化, 而只是一个很浅显的道理
既然经常用到的功能我们需要给它独立写一个函数,那为什么经常用到的句柄我们就不能给它独立申明呢?
试想一下, 如果每个函数都调用楼主的日志函数, 那这个开销就不可估量了
的确现在的硬件发展很迅速, 但并不是每个客户都使用这些高端设备
小型商铺、车间电脑、一般的办公计算机等等这些在我的客户群里占了90%以上
这90%里面有起码50%用的还是单核计算机,车间用的电脑有的还是 win98
开发人员需要跟上时代的步伐这没错,但也得结合实际应用而考虑
你不可能说出了iPhone6就不去考虑iPhone4的用户
能用得上你所说这些设备的能有多少?那么在这些人里面真正会使用商业软件的人又有多少?
请老实回答我,你用过哪怕一次profiler功能查看程序实际运行时的性能瓶颈在哪里吗?
Using PROFILE, PREP, and PLIST
Home
------解决思路----------------------
Overview
------解决思路----------------------
Details
Feature Only in Professional and Enterprise Editions Profiling is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.
Profiling requires three separate programs: PREP, PROFILE, and PLIST. When you choose a standard option (other than Custom) from the Profile dialog box, the development environment executes these programs for you automatically, passing arguments to the PREP program.
If you want maximum profiling flexibility, including the ability to format your output and to specify function and line-count profiling, you must write your own batch files that invoke PREP, PROFILE, and PLIST. You can run these batch files from either the Profile dialog box or from the command prompt. If you run the batch file from the dialog box, the PLIST output will, by default, be routed to the output window. Command-line batch output can also be routed to a file.
The following figure illustrates the profiler batch processing flow.
Profiler Batch Processing Flow
Notice that the PREP program is called twice. Phase I is before the actual profiling and Phase II is after the profiling. The command-line arguments govern PREP’s behavior.
The .PBI, .PBO, and .PBT files are intermediate files that are used to transfer information between profiling steps. The broken lines indicate connections that depend on the PREP (Phase I) command-line options.
A typical profiler batch file might look like this:
PREP /OM /FT /EXC nafxcwd.lib %1
if errorlevel == 1 goto done
PROFILE %1 %2 %3 %4 %5 %6 %7 %8 %9
if errorlevel == 1 goto done
PREP /M %1
if errorlevel == 1 goto done
PLIST /SC %1 >%1.lst
:done
Note When you run a profiler batch file from the Profile dialog box using the Custom option, the PLIST standard output is routed to the Profile tab in the Output window. In the preceding batch file, the PLIST output is redirected to a file, as it would usually be in a batch file run from the command line.
When the batch file is run using the Custom option in the Profile dialog box, the development environment substitutes the project’s program name for the %1 parameter. You can specify your program’s command-line arguments on the Debug tab in the Project Settings dialog box.
If the preceding batch file was named FTIME.BAT, and you wanted to profile the program TEST from the Profile dialog box, you would select the Custom option, and then specify FTIME.BAT in the Custom Settings box. If you wanted to profile the TEST program from the command prompt, you would type:
FTIME TEST
Note If you are running a profiler batch file from the development environment, you can edit your batch file. Remember to save your batch files after editing, because the development environment does not save them automatically.
------解决思路----------------------
我所说的是一个编程意识
------解决思路----------------------
我所说的是一个编程意识
很多过去屡试不爽的编程意识,到现在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代早已经过时了。