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 |