THotLog output examples



Here are some examples of what can be outputed to a log file using HotLog.Pas / THotLog freeware unit.

They are relatively basic. More complex outputs are left to your imagination. THotLog possibilities are huge...


All the examples below use an instance of THotLog called hLog. This instance is created automatically at your application's startup. As long as it is ready to use, we won't change anything to it's default settings. In consequence, the log file would be created in our exe directory, with the name of this exe, and '.log' as extention. Note however, that all this could have been changed easily.
The only line to add to your code before logging datas is

hLog.Startlogging;

which resumes the threads in charge of the logging process. Once called, you can start adding lines in the log, using one of the provided routine (function or procedure), like for example :

hLog.Add
('A first line');

which will (not so surprisingly) add a line into the log file, containing :

A first line




Exceptions and errors logging is made easy too, with some overloaded procedure definitions. The errors and exceptions logging output depends on some settings which are detailed in the help file. Logging an exception can be as simple as (THotLog needed line appear in red) :

Function DoDivide(x,y:Integer):Integer;
  Begin
    Result := -1; 
    TRY
      // If y is worth zero, an EZeroDivide
      //
exception will - obviously - occur...
      Result := x div y;
    EXCEPT        
      //
Logg the exception message
      On E:Exception Do
        hLog.AddException(E);         // nothing else to do.
      {...};
    END;
  End;


  Which will add these lines to the log (
depending on the settings you choosed)  :

•••••••••••••••••••••••
•••    E R R O R    •••   "Division by zero"
•••••••••••••••••••••••


A bit few isn't it ? To have more informations added in your log file about the exception that occured, you can use the oveloaded definition of the AddException( ); procedure (THotLog needed line appear again in red). This definitions waits for the exception that occured, together with :
  • a string, that is considered by THotLog exception handling procedures to be the name of the routine where the exception occured
  • an optionnal array of const, that can contain everything you want, and is mainly intended to receive the paramters your routine received, and, why not, some local or global variables.

Function DoSomethingAndDivide(Sender:TObject;x,y,z:Integer;aString:String):Integer;
  Begin
    Result := -1; 
    TRY
      {...}
      // If y or z are worth zero, an EZeroDivide
      //
exception will occur...
      Result := Abs(x div (y*z));
    EXCEPT        
      // Loggs the exception message and arguments received.
      // Note that arguments to logg are directly passed
      //
to hLog without transtyping, or anything like that ;
      On E:Exception Do
hLog.AddException(E,'DoSomethingAndDivide',[Sender,x,y,z,aString]);
        {...};
    END;
  End;


Like above, the settings you choosed for exception displaying impact the result. Depending on these settings (in this example, hLog's  errorViewStyle is set to vsExtended), the result would be :


••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
•••    E R R O R    •••   "Division by zero" in function :
•••••••••••••••••••••••    DoSomethingAndDivide( TObject    : Button1 (TButton, "Compute");
                                                 Integer    : 1;
                                                 Integer    : 0;
                                                 Integer    : -547;
                                                 AnsiString : Some string pointed at by aString  )
••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••

 
You can pass anything into the array, thus being able to log valuable informations about your variables contents at the time an error occurs, simplifying a lot the debbuging process.


Variant open array parameters are used in one of the overloaded definitions of THotLog.Add( ); procedure too. Such arrays can then be used anywhere in your code, not only when exceptions occur. Moreover, THotLog string formating capabilities allow to format the output the way you want (see THotLog help file).


THotLog can retrieve some informatons about the environment your programm is running into. It can
format strings too.
All these operations are made through tags, embeded in the strings you want to log, and sent to the parser through the three overloaded definitions of the
hLog.Add( ); procedure, which is the main logging routine.
  • The first one waits for a string ;
  • The second one waits for a stringList ;
  • The third one waits for an "array of const" ("vatiant open array parameter") ;
Using tags instead of dedicated procedures, to retrieve informations alloweded to avoid adding more and more procedure and functions. A little number is far enough to do most of the job.

Tags are made of string surrounded by brackets.

Here are some examples of informations that can be retrieved :



hLog.add('{OSVI}') ;                 //  Retrieves OS version info


===============================  OS version info  =================================
  Platform  : Windows NT, Windows 2000, Windows XP, or Windows Server 2003 family.
  OS Name   : Windows XP (Service Pack 1)( (Personal))
  (Major Version[ 5 ]  Minor Version[ 1 ] Build Number[ 2600 ]  Platform ID[ 2 ])
===================================================================================


hLog.add('{Heap}') :                 //  Retrieves heap informations

===========  Heap Monitor  ============
  AllocMemCount (Blocks) : 534
  AllocMemSize  (Bytes)  : 37668
=======================================




hLog.add('{Timers}') :                 //  Retrieves timing capacities of the local environment

===========================================  Timers resolution  ===========================================
                          |                Min resolution                 |       Api \ call overhead
          Timers          |-----------------------------------------------|--------------------------------
                          |       ms      :       µs      :      ns       |    native    :    optimal    
--------------------------|-----------------------------------------------|--------------------------------
  GetTickCount            |  15,---       :      n/s      :      n/s      |     0 ticks  : ms or s.
  QueryPerformanceCounter |   0,000000334 :   0,000334165 :   0,334165405 |   665 units  : µs (0,222219994)
  ReaDTimeStampCounter    |   0,000000334 :   0,000334225 :   0,334224599 |    88 cycles : ns (29,411764706)
============================================================================================================
                                                                (n/a: not available, n/s : not significant)
                                             QueryPerformanceFrequency returned : 2992530000 (native units)
                                              (RDTSC min resolution from registry ; Overhead from asm call)
============================================================================================================


The example above illustrates the use of the TQTimer definition embeded in HotLog.pas file, which is able to convert a timing measure to a time unit, and select the most easy to read time unit to use for displaying the result.
For instance, the right most column above, of the line QueryPerformanceCounter, gives the time cost of a call to the API in native units ("665") and in micro seconds 0,222219994, instead of nanoseconds or miliseconds, because 0.222 is considered to be easier to read and more significant  than 0.000222 (miliseconds) or 222.21999... (nanoseconds). On the contrary, TQTimer choosed to express the RDTSC call overhead in nanoseconds, for the same reasons.
This is done automatically, if you set the TQTimer's instance showOptimalUnit boolean parameter to True. (and obviously, the unit of your choice is used if you set it to False...)



Formating strings is made possible by tags :

HLog.Add('{@5}-> Entering function{*25.}: ' + SomeFuncName + '{70@}{&}{HMS}-{GTC}{&}');
HLog.Add('{@5}-> Exiting{*25.}: ' + SomeFuncName + '{70@}{GTC}');


Would output :

     -> Entering function.....: MyFunction             19:31:09-5738500
     -> Exiting...............: MyFunction                      5758312





Mixing Environment and formatting tags is possible too :

THotLog's "header" and "footer" variables are examples of this :

// They are defined that way :
  Self.header := TstringList.Create;
With Self.Header Do
Begin
Add('{crlf}{LNumOff}{*80*}');
Add('>>>> Start {App_name} v {App_ver}{80@}{now}');
Add('{@12}From : {App_path}');
Add('{@12}Prms : {App_prm-}{crlf}');
End;

Self.footer := TStringList.Create;
With self.Footer Do
Begin
Add('{LNumOff}');
Add('<<<< Stop {App_name}{80@}{now}');
Add('{*80*}{crlf}');
End;

// They are added to the log file that way :

hLog.Add ( header ) ;
  {...}
hLog.Add ( footer ) ;


// and the written result will be :

********************************************************************************
>>>> Start HotLogTest.exe  v 1.0.0.4                         2004-03-09 23:38:54
           From : C:\Program Files\Borland\Delphi6\Projects\HotLog\
           Prms : (No params)

(... lines logged ...)

<<<< Stop  HotLogTest.exe                                    2004-03-09 23:38:55
********************************************************************************



Finally, here is an example using the third form of hLog.add( );
The example may seem a bit stupid (I warned you that the imagination job was yours...), but illustrates that variables of different types, and formatting tags can be mixed to obtain the wanted result.

procedure TForm1.Button8Click(Sender: TObject);
var i: real;
s: String;
begin
Randomize;
i := Random;
s := TimeToStr(now);
hLog.Add(vsNone,['Here are some datas to format and output{/}',
'{@12}-> This one is number{@40} : ',1,'{/}',
'{@12}-> and this one is number{@40} : ',2,'{/}',
'{@12}-> the third one is {@40} : ',3,'{/}',
'{/}By the way, "i" value is{@40} : ',i, '{/}',
'and the time part of "now()" function (',now,') {/}translates to {@40} : ',s ,
'{/}{/}You can see the whole bunch mixes integers, real, and strings (including tags) whithout problems...']);
end;

// Will output :


Here are some datas to format and output
          
-> This one is number        : 1
          
-> and this one is number    : 2
          
-> the third one is          : 3

By the way, "i" value is                : 0,990934341913089
And the time part of "now()" function (38060,9705908102)
translates to                           : 23:17:39


You can see the whole bunch mixes integers, real, and strings (including tags) whithout problems...


________________________

(c) 2004 Olivier Touzot   Top