Delphi输出日志的方法
1、使用OutputDebugString
procedure TForm1.BtnDebugClick(Sender: TObject); begin //这里调用OutputDebugString发送调试信息到调试器。在Delphi //里面,用View - Debug Windows - Event Log 来查看。 OutputDebugString(PChar('测试OutputDebugString')); end;
很简单。这个函数是Windows提供的,专门用来进行调试。调用后,将把字符串发送给当前的调试器。 对于Delphi来说,就是Delphi IDE本身。在程序运行的时候,可以通过View - Debug Windows - Event Log 来查看,如图:
2、发送日志到操作系统日志记录。
这个基本上使用在Release版本中,记录一些重要的信息,帮助用户反馈信息给开发人员。 procedure TForm1.BtnEventClick(Sender: TObject); var h,b:THandle;
msg:String;
p:Pointer;
i:integer;
size:integer;
q:^byte; begin
//注册事件源,随便起了个名字。这个名字就是下图事件列表的’来源’一列
//然后判断是否成功。
//注意后面要注销 h:=RegisterEventSource(nil, 'test1'); if h =
0 then
begin
ShowMessage('注册事件源失败!');
Exit;
end;
//这里记录一个字符串
//这个字符串显示在下面第二个图选中的位置。
msg:='记录字符串';
ReportEvent(h,EVENTLOG_INFORMATION_TYPE,0, 0, nil, 1, 0, @msg, nil);
//这里记录一块内存,size大小
size:=32;
//申请
GetMem(p, size);
q:=p; //填充这块内存 for i:=0 to size -
1
do begin q^:=i;
inc(q); end;
//这里记录内存的内容。大小为size, 首字节的指针p
//同样也有说明信息msg
msg:='记录某块内存';
ReportEvent(h,EVENTLOG_INFORMATION_TYPE , 0, 0, nil, 1, size, @msg, p); FreeMem(p);
//注销事件源
DeregisterEventSource(h); end;
程序运行后,可以通过控制面板 – 管理工具 – 事件查看器来查看。上面的代码运行结果如图:
双击第一个事件,如图:
双击第二个事件,如图:
3.重写Assert
Delphi内置了Assert调试过程,语法是
Assert(cond, msg);
如果cond为false,那么显示错误信息msg,并且触发异常(可在IDE里中断)。
因为这个函数是编译器内置的,里面提供了源代码文件名、行号的信息,所以可以通过重写这个函数,完成日志记录的功能: 1、加入初始化代码,保存旧的Assert函数地址,然后将新的赋入:
initialization
oldAssertErrorProc := AssertErrorProc;
AssertErrorProc:=@OtherAssertProc;
其中,新函数OtherAssertProc如下: procedure OtherAssertProc(const Message, Filename: string;
LineNumber: Integer; ErrorAddr: Pointer); Var runErrMsg:String;
begin runErrMsg := format('Error: %s, in file(%d): %s, Addr: %p',
[Message, LineNumber, FileName, ErrorAddr]); if IsConsole then
Writeln(runErrMsg)
else
MessageBox(0, pChar(runErrMsg), 'Error Log by AssertLogs', 0); end;
2、在程序中,就可以使用
Assert(false, msg);来进行调用了。因为我们使用Assert来记录信息,所以条件一定是false保证函数被调用。 运行结果如下图:
这是通过MessageBox函数输出的,当然也可以通过其他方式显示或者记录。
3、最后,将AssertErrorProc恢复初始值: finalization AssertErrorProc := oldAssertErrorProc;
4、JCL库
JCL库是著名的开源Delphi库,包括大量的函数、类,基本上分为系统、日期、调试、字符串等等。 其中的JCLDebug库可以方便的列出代码的调用情况,也可以做到类似与Java的逐层打印调用栈。运行情况如下图:
代码为: //这是一个日志函数,拼装日志信息 function log(S:String):String; var
f, proc:String;
line:Integer;
r:String; begin f:=FileByLevel(1); //获得调用它的文件名
line:=LineByLevel(1); //获得调用它的行号
proc:=ProcByLevel(1); //获得调用它的模块名 Result:= f +
':'
+ IntToStr(line) +
'
'
+ proc +
'
'
+ S; end; |
|