views:

407

answers:

2

Hello and good morning!

Unfortunately I am not writing this question from my Developing PC so I might do some mistakes. Please sorry about it... So - my question - what approach you use to implement error logging in your application?

In web ( http://delphi.about.com ) is nice event handler, but it just copies system error in file, but I would like to expand its capabilities by trapping memory and stack ( and processor information, if I will have time ). Should I aware if I call it dynamically, not adding its component on the form?

procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception) ;
var
   ErrorLogFileName : string;
   ErrorFile : TextFile;
   ErrorData : string;
begin
   ErrorLogFileName := ChangeFileExt(Application.ExeName,'.error.log') ;
   AssignFile(ErrorFile, ErrorLogFileName) ;

   //either create an error log file, or append to an existing one
   if FileExists(ErrorLogFileName) then
     Append(ErrorFile)
   else
     Rewrite(ErrorFile) ;

   try
     //add the current date/time and the exception message to the log
     ErrorData := Format('%s : %s',[DateTimeToStr(Now),E.Message]) ;
     WriteLn(ErrorFile,ErrorData) ;
   finally
     CloseFile(ErrorFile)
   end;

   //Show the exception
   Application.ShowException(E) ;
end;

... and http://delphi.about.com/cs/adptips2001/a/bltip0101_2.htm

As we know, Delphi also provides memory management a bit like C - using ampersands and Pascal functions, but what would be the most effective logging?

Thanks before! Hopefully this topic will be useful to other quality programmers.

+3  A: 

IIUC, you want a stack trace report with line numbers, system info etc. IOW something like this:

Exception class: EVariantTypeCastError
Exception address: 004170ED
------------------------------------------------------------------------------
Stack list, generated 12/7/2009 11:32:19
[004170E8]{A.exe       } Variants.HandleConversionException (Line 614, "sys\variants.pas" + 10)
[0057ACAC]{A.exe       } cxDataStorage.TcxSmallintValueType.SetDataValue (Line 1067, "cxDataStorage.pas" + 2)
[005AC6C5]{A.exe       } cxCustomData.TcxCustomDataController.SetStoredValue (Line 12752, "cxCustomData.pas" + 2)
[005A8AD3]{A.exe       } cxCustomData.TcxCustomDataController.SetValue (Line 10401, "cxCustomData.pas" + 12)
[0059DA0B]{A.exe       } cxCustomData.TcxCustomDataProvider.SetEditValue (Line 3180, "cxCustomData.pas" + 4)
[005A8F9B]{A.exe       } cxCustomData.TcxCustomDataController.SetEditValue (Line 10560, "cxCustomData.pas" + 2)
[0066EBBE]{A.exe       } cxGridCustomTableView.TcxCustomGridTableItem.SetEditValue (Line 14396, "cxGridCustomTableView.pas" + 1)
[006637C5]{A.exe       } cxGridCustomTableView.TcxGridEditingController.UpdateValue (Line 7474, "cxGridCustomTableView.pas" + 4)
[00673F30]{A.exe       } cxGridCustomTableView.TcxCustomGridTableView.UpdateRecord (Line 17771, "cxGridCustomTableView.pas" + 1)
[0059D97F]{A.exe       } cxCustomData.TcxCustomDataProvider.PostEditingData (Line 3170, "cxCustomData.pas" + 1)
[00A80870]{A.exe       } fFilterLine.TFilterLine.UMLayoutChanged (Line 1034, "fFilterLine.pas" + 0)
[00482DBF]{A.exe       } Controls.TWinControl.WndProc (Line 7304, "Controls.pas" + 111)
[004824E8]{A.exe       } Controls.TWinControl.MainWndProc (Line 7073, "Controls.pas" + 3)
[00431D84]{A.exe       } Classes.StdWndProc (Line 11583, "common\Classes.pas" + 8)
[0049F981]{A.exe       } Forms.TApplication.MessageBox (Line 8293, "Forms.pas" + 22)
[0049FA99]{A.exe       } Forms.TApplication.ShowException (Line 8312, "Forms.pas" + 3)
[00A7D7B1]{A.exe       } ExceptionDlg.TfrmException.ExceptionHandler (Line 428, "..\Shared\ExceptionDlg.pas" + 2)

...
<snipped>
...

------------------------------------------------------------------------------
System   : Windows XP Professional, Version: 5.1, Build: A28, "Service Pack 2"
Processor: Intel, Intel(R) Core(TM)2 Quad CPU    Q6700  @ 2.66GHz, 2666 MHz MMX 64 bits
Memory: 1043; free 196
Display  : 1920X1200 pixels, 32 bpp
------------------------------------------------------------------------------
Active Controls hierarchy:
TcxCustomInnerTextEdit ""
TcxTextEdit ""
TcxGridSite ""
TcxGrid "cxgHeader"
TPanel "pnlMain"
TTabSheet "tshAccMov"
TPageControl "pcoMov"
TfrmMain "frmMain"
------------------------------------------------------------------------------

...well, imho, isn't worth to reinvent the wheel. This has already been done and it's free. Download (if you haven't already) the JEDI's JVCL+JCL from SourceForge and install them. In File | New | Other | Delphi Files... you'll have a new item: 'Jcl Exception dialog for Delphi'.

And (imho) this is much more mature/advanced than you can do 'if you'll have time'. Also you can customize the generated Exception Handler to fit to your needs. There is also a support newsgroup for this. As an aside, IIRC, you need only the JCL for the dialog but I'm not sure. Also, you have also commercial options for this (madExcept, EurekaLog etc.) but these are only advanced Error Loggers while JVCL, besides that's free, will give you also over 600 components to play with.

HTH

+4  A: 

Might be worth looking at third party components instead of writing something yourself. Both EurekaLog and madExcept do pretty much exactly what you're after. Both give great output and have support to connect into bug tracking systems like FogBugz, Mantis and BugZilla. With that you can actually collate the bug reports you're getting, spot common patterns and hopefully fix bugs quicker.

Personally, installing the Jedi JVCL / JCL is a bit overkill for just it's exception tracking since it's a fairly hefty install. Both of the above I've mentioned are commercial products, but you get what you pay for.

Pauk
madExcept is absolutely great, highly recommended!
onnodb
+1 for EurekaLog! ;)
Pauk