Sign in Join
Wiki copytemporary

MultiLog: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: MultiLog

OldNewLine
1+### About
2+
3+MultiLog is a log system that aims at flexibility and low overhead at the same time. As the name suggests, it can be used to log to several targets such as a text file, a visual control or to another application. Adding new targets is as easy as creating a class that implements two methods, one being optional.
4+
5+MultiLog is in general similar to [CodeSite](http://www.raize.com/DevTools/CodeSite/), [Smart Inspect](http://www.gurock.com/products/smartinspect/), [Overseer](https://sourceforge.net/projects/nexusproject/) and [EstLogger](http://estlogger.sourceforge.net/) but it does not follow closely any of them, implementing many things differently and, even, having some unique features.
6+
7+Starting from version 0.5, the base library can be compiled with Delphi.
8+
9+Features:
10+
11+- Flexible:
12+ - It's possible to define up to 32 log classes and enable/disable any combination of them
13+ - Each message can be associated with more than one class
14+ - There's overloaded functions for most used types: Integer, Float, Boolean, String, TStrings, TRect, TPoint
15+- Low overhead:
16+ - If a log class is not active, all messages that belongs to it only do a check in the begin of the function and exit
17+ - In the future a fake TLogger class will be provided, so the overhead will be even smaller if desired
18+- Main features found in the cited Log Systems are implemented:
19+ - SendException
20+ - Watches
21+ - Named Counters
22+ - Send TObject/TComponent, TBitmap, Memory info
23+ - A log viewer application (MultiLog Viewer) with ability to track watches, callstack and filter messages
24+- Unique:
25+ - Implements conditional messages (using SendIf method): a message is sent if a boolean criterium is met
26+ - Implements a function (CalledBy) that returns if the current code was called by a method (Useful to debug the LCL)
27+ - Implements SendCallStack and SendHeapInfo: the name says it all
28+ - Named CheckPoints
29+ - Ability to send custom messages through [[callback]] functions
30+
31+Here's the provided Log Viewer in action:
32+
33+<figure>
34+<img src="Multilogviewer.png" title="Multilogviewer.png" />
35+<figcaption>Multilogviewer.png</figcaption>
36+</figure>
37+
38+### Author
39+
40+Luiz Américo Pereira Câmara aka Karl Brandt
41+
42+Contact: pascalive at bol(dot)com(dot)br
43+
44+### License
45+
46+Modified LGPL
47+
48+### Download
49+
50+MultiLog library and MultiLogViewer: <https://github.com/blikblum/multilog>
51+
52+### Change Log
53+
54+- 22/07/13
55+ - MultiLog 0.6
56+ - Improve compatibility with recent versions of Lazarus/LCL
57+ - Improve TObject/TComponent streaming
58+- 29/03/08
59+ - MultiLog 0.5
60+ - Can be compiled with Delphi
61+ - Enable inline
62+ - Several fixes
63+ - MultiLog Viewer 0.3
64+ - Added ability to see a watch history
65+ - Improved GUI usability
66+- 19/05/2007 - MultiLog 0.4
67+ - Changed license to modified LGPL
68+ - Added named counters
69+ - A message can be associated with more than one class
70+- 11/02/2007 - Multilog 0.3/Multilog Viewer 0.2
71+ - Multilog
72+ - Added SendCustomData, SendMemory methods
73+ - Added a TLogger descendant (TLCLLogger) which can send LCL specific data (TBitmap for now)
74+ - Cleaned the code
75+ - Multilog Viewer
76+ - Ability to display a memory area as hex values
77+ - Ability to display bitmaps
78+ - Improved usability
79+- 06/08/2006 - Multilog 0.2
80+ - Implemented overloaded Send method for TObject and Float
81+ - Implemented Watches
82+ - Implemented CheckPoints
83+ - Implemented SendHeapInfo and SendException
84+ - Created a full LogViewer (MultiLog Viewer 0.1) with support for Watches, CallStack and message filtering
85+- 12/06/2006 - Multilog 0.1
86+ - Initial release
87+
88+### System Requirements
89+
90+- Base Library (MultiLog unit)
91+ - fpc 2.2.0
92+- LCL (MultilogLCL unit)
93+ - Lazarus 0.9.24 or above
94+- SimpleLogViewer
95+ - Lazarus 0.9.24 or above
96+- Multilog Viewer
97+ - Lazarus 0.9.24 or above
98+ - MultiLog
99+ - [Virtual Treeview](https://luipack.bountysource.com/wiki/virtualtreeview)
100+ - [ATBinHex](https://luipack.bountysource.com/wiki/atbinhex)
101+ - [Unique Instance](http://wiki.lazarus.freepascal.org/UniqueInstance)
102+ - [Lui Controls](https://luipack.bountysource.com/wiki/luicontrols)
103+
104+### Usage
105+
106+- Some usage examples can be found [here](https://luipack.googlecode.com/svn/wiki/MultiLog.wiki)
107+- See the examples included in the demos folder
108+
109+#### Simple example
110+
111+Install multiloglaz package into Lazarus and build MultiLogViewer from it's Viewer directory. Create new application, and add 4 buttons, 1 spinedit, and 1 panel to main form. Replace code with the one below. Start MultiLogViewer, run your application and logging will start. Since we have added both ipc and file channels for logging (in Form's OnCreate method), even if MultiLogViewer is not started we will have logging to 'debug.log' file.
112+
113+``` pascal
114+unit Unit1;
115+
116+{$mode objfpc}{$H+}
117+
118+interface
119+
120+uses
121+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
122+ Spin, ExtCtrls, MultiLog {must be included for Multilog logging},
123+ ipcchannel {logging over IPC channel to MultiLog Viewer application},
124+ filechannel {logging over file channel to log file};
125+
126+type
127+
128+ { TForm1 }
129+
130+ TForm1 = class(TForm)
131+ Button1: TButton;
132+ Button2: TButton;
133+ Button3: TButton;
134+ Button4: TButton;
135+ Panel1: TPanel;
136+ SpinEdit1: TSpinEdit;
137+ procedure Button1Click(Sender: TObject);
138+ procedure Button2Click(Sender: TObject);
139+ procedure Button3Click(Sender: TObject);
140+ procedure Button4Click(Sender: TObject);
141+ procedure FormCreate(Sender: TObject);
142+ procedure FormDestroy(Sender: TObject);
143+ procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
144+ procedure Panel1MouseEnter(Sender: TObject);
145+ procedure Panel1MouseLeave(Sender: TObject);
146+ procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
147+ procedure SpinEdit1Change(Sender: TObject);
148+ private
149+
150+ public
151+
152+ end;
153+
154+var
155+ Form1: TForm1;
156+
157+implementation
158+
159+{$R *.lfm}
160+
161+{ TForm1 }
162+
163+procedure TForm1.FormCreate(Sender: TObject);
164+begin
165+ Logger.Channels.Add(TFileChannel.Create('debug.log')); // switch on file logging
166+ Logger.Channels.Add(TIPCChannel.Create); // switch on ipc logging
167+ Logger.Send('----------------------------------------------------');
168+ Logger.Send('Form1 created');
169+end;
170+
171+procedure TForm1.FormDestroy(Sender: TObject);
172+begin
173+ Logger.Send('Form1 destroyed');
174+end;
175+
176+procedure TForm1.Button1Click(Sender: TObject);
177+begin
178+ Logger.IncCounter('MyLogCounter');
179+end;
180+
181+procedure TForm1.Button2Click(Sender: TObject);
182+begin
183+ Logger.ResetCounter('MyLogCounter');
184+end;
185+
186+procedure TForm1.Button3Click(Sender: TObject);
187+begin
188+ Logger.Watch('MyLogWatch', Caption);
189+end;
190+
191+procedure TForm1.Button4Click(Sender: TObject);
192+var
193+ Exc: EMathError;
194+begin
195+ try
196+ Exc := EMathError.Create('fake math exception');
197+ raise Exc;
198+ except
199+ on E: Exception do Logger.SendException('Exception: Force fake math exception', E);
200+ end;
201+end;
202+
203+procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
204+begin
205+ Logger.Send('Panel1MouseDown');
206+end;
207+
208+procedure TForm1.Panel1MouseEnter(Sender: TObject);
209+begin
210+ Logger.Send('Panel1MouseEnter');
211+end;
212+
213+procedure TForm1.Panel1MouseLeave(Sender: TObject);
214+begin
215+ Logger.Send('Panel1MouseLeave');
216+end;
217+
218+procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
219+begin
220+ Logger.Send('Panel1MouseUp');
221+end;
222+
223+procedure TForm1.SpinEdit1Change(Sender: TObject);
224+begin
225+ Logger.EnterMethod('SpinEdit1Change');
226+ try
227+ Caption := 'New SpinEdit1 value is ' + IntToStr(SpinEdit1.Value);
228+ Logger.Send('SpinEdit1.Value', SpinEdit1.Value);
229+ finally // we want to make sure that each EnterMethod is paired with it's Exitmethod
230+ Logger.ExitMethod('SpinEdit1Change');
231+ end;
232+end;
233+
234+end.
235+```
236+
237+This is how the result should look like in runtime (if you replace default captions as shown):
238+
239+<figure>
240+<img src="MultiLogSimpleDemo.png" title="MultiLogSimpleDemo.png" />
241+<figcaption>MultiLogSimpleDemo.png</figcaption>
242+</figure>
243+
244+<figure>
245+<img src="MultiLogViewerForSimpleDemo.png" title="MultiLogViewerForSimpleDemo.png" />
246+<figcaption>MultiLogViewerForSimpleDemo.png</figcaption>
247+</figure>
248+
249+If you want your logged exceptions and stacks to show source code line numbers of the runtime error like on the screenshot above then go to Project / Project Options / Compiler Options / Debugging and switch on check boxes for 'Generate debugging info for GDB' and 'Display line numbers in run-time error backtraces'.
250+
251+### Known Issues
252+
253+- ~~In my setup (Lazarus 0.9.17 + fpc 2.0.4rc2 + Windows XP), is necessary add the directory where is the package sources to the Units path in the Compiler Options. This occurs, i think, because fpc tries to recompile a unit even after finding it in \$(PkgDir)\lib\\\$(TargetCPU)-\$(TargetOS)\\. It seems a fpc bug since sometimes a Internal Error is given~~
254+ - ~~To override this problem since version 0.2 the unit path of the lazarus package points to \$(PkgDir). This has the drawback of breaking the "multienviroment" schema that separates binaries of different targets used in most packages.~~
255+ - ~~As a side effect when compiling projects that requires multilog package, fpc will create duplicated units in the project path and Lazarus IDE warn about them. Just ignore the warnings.~~
256+- ~~While developing MultiLog i had some problems with inlines (See this [bug](http://www.freepascal.org/mantis/view.php?id=7107)). All inlines were commented. Because of this all calls to the overloaded SendCallStack that has a implicit classes (DefaultClasses) will have SENDCALLSTACK as the first frame. Use the explicit SendCallStack overloaded function as a workaround.~~
257+ - ~~Waiting for fpc2.2 to re-enable inline.~~
258+
259+### See also
260+
261+- [[doc:fcl/eventlog/teventlog.html|TEventLog documentation]] Built in support for logging in FPC/Lazarus
262+- [[LazLogger]] Logging support supplied with Lazarus
263+- [[log4delphi]] Another Lazarus logging framework ported from Delphi
264+
265+---
266+*From the Free Pascal wiki, page "MultiLog", as it stood on 2021-10-25 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
267+Category: Components
268+Category: Lazarus
269+Category: Lazarus-CCR
270+Category: Logging

Back to history