Sign in Join
Wiki copytemporary

MultiLog: what changed

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

OldNewLine
11### About
22
33MultiLog 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.
44
55MultiLog 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.
66
77Starting from version 0.5, the base library can be compiled with Delphi.
88
99Features:
1010
1111- Flexible:
1212 - It's possible to define up to 32 log classes and enable/disable any combination of them
1313 - Each message can be associated with more than one class
1414 - There's overloaded functions for most used types: Integer, Float, Boolean, String, TStrings, TRect, TPoint
1515- Low overhead:
1616 - 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
1717 - In the future a fake TLogger class will be provided, so the overhead will be even smaller if desired
1818- Main features found in the cited Log Systems are implemented:
1919 - SendException
2020 - Watches
2121 - Named Counters
2222 - Send TObject/TComponent, TBitmap, Memory info
2323 - A log viewer application (MultiLog Viewer) with ability to track watches, callstack and filter messages
2424- Unique:
2525 - Implements conditional messages (using SendIf method): a message is sent if a boolean criterium is met
2626 - Implements a function (CalledBy) that returns if the current code was called by a method (Useful to debug the LCL)
2727 - Implements SendCallStack and SendHeapInfo: the name says it all
2828 - Named CheckPoints
2929 - Ability to send custom messages through [[callback]] functions
3030
3131Here's the provided Log Viewer in action:
3232
33-<figure>
34-<img src="Multilogviewer.png" title="Multilogviewer.png" />
35-<figcaption>Multilogviewer.png</figcaption>
36-</figure>
33+![](/wiki-images/2/20/Multilogviewer.png)
3734
3835### Author
3936
4037Luiz Américo Pereira Câmara aka Karl Brandt
4138
4239Contact: pascalive at bol(dot)com(dot)br
4340
4441### License
4542
4643Modified LGPL
4744
4845### Download
4946
5047MultiLog library and MultiLogViewer: <https://github.com/blikblum/multilog>
5148
5249### Change Log
5350
5451- 22/07/13
5552 - MultiLog 0.6
5653 - Improve compatibility with recent versions of Lazarus/LCL
5754 - Improve TObject/TComponent streaming
5855- 29/03/08
5956 - MultiLog 0.5
6057 - Can be compiled with Delphi
6158 - Enable inline
6259 - Several fixes
6360 - MultiLog Viewer 0.3
6461 - Added ability to see a watch history
6562 - Improved GUI usability
6663- 19/05/2007 - MultiLog 0.4
6764 - Changed license to modified LGPL
6865 - Added named counters
6966 - A message can be associated with more than one class
7067- 11/02/2007 - Multilog 0.3/Multilog Viewer 0.2
7168 - Multilog
7269 - Added SendCustomData, SendMemory methods
7370 - Added a TLogger descendant (TLCLLogger) which can send LCL specific data (TBitmap for now)
7471 - Cleaned the code
7572 - Multilog Viewer
7673 - Ability to display a memory area as hex values
7774 - Ability to display bitmaps
7875 - Improved usability
7976- 06/08/2006 - Multilog 0.2
8077 - Implemented overloaded Send method for TObject and Float
8178 - Implemented Watches
8279 - Implemented CheckPoints
8380 - Implemented SendHeapInfo and SendException
8481 - Created a full LogViewer (MultiLog Viewer 0.1) with support for Watches, CallStack and message filtering
8582- 12/06/2006 - Multilog 0.1
8683 - Initial release
8784
8885### System Requirements
8986
9087- Base Library (MultiLog unit)
9188 - fpc 2.2.0
9289- LCL (MultilogLCL unit)
9390 - Lazarus 0.9.24 or above
9491- SimpleLogViewer
9592 - Lazarus 0.9.24 or above
9693- Multilog Viewer
9794 - Lazarus 0.9.24 or above
9895 - MultiLog
9996 - [Virtual Treeview](https://luipack.bountysource.com/wiki/virtualtreeview)
10097 - [ATBinHex](https://luipack.bountysource.com/wiki/atbinhex)
10198 - [Unique Instance](http://wiki.lazarus.freepascal.org/UniqueInstance)
10299 - [Lui Controls](https://luipack.bountysource.com/wiki/luicontrols)
103100
104101### Usage
105102
106103- Some usage examples can be found [here](https://luipack.googlecode.com/svn/wiki/MultiLog.wiki)
107104- See the examples included in the demos folder
108105
109106#### Simple example
110107
111108Install 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.
112109
113110``` pascal
114111unit Unit1;
115112
116113{$mode objfpc}{$H+}
117114
118115interface
119116
120117uses
121118 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
122119 Spin, ExtCtrls, MultiLog {must be included for Multilog logging},
123120 ipcchannel {logging over IPC channel to MultiLog Viewer application},
124121 filechannel {logging over file channel to log file};
125122
126123type
127124
128125 { TForm1 }
129126
130127 TForm1 = class(TForm)
131128 Button1: TButton;
132129 Button2: TButton;
133130 Button3: TButton;
134131 Button4: TButton;
135132 Panel1: TPanel;
136133 SpinEdit1: TSpinEdit;
137134 procedure Button1Click(Sender: TObject);
138135 procedure Button2Click(Sender: TObject);
139136 procedure Button3Click(Sender: TObject);
140137 procedure Button4Click(Sender: TObject);
141138 procedure FormCreate(Sender: TObject);
142139 procedure FormDestroy(Sender: TObject);
143140 procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
144141 procedure Panel1MouseEnter(Sender: TObject);
145142 procedure Panel1MouseLeave(Sender: TObject);
146143 procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
147144 procedure SpinEdit1Change(Sender: TObject);
148145 private
149146
150147 public
151148
152149 end;
153150
154151var
155152 Form1: TForm1;
156153
157154implementation
158155
159156{$R *.lfm}
160157
161158{ TForm1 }
162159
163160procedure TForm1.FormCreate(Sender: TObject);
164161begin
165162 Logger.Channels.Add(TFileChannel.Create('debug.log')); // switch on file logging
166163 Logger.Channels.Add(TIPCChannel.Create); // switch on ipc logging
167164 Logger.Send('----------------------------------------------------');
168165 Logger.Send('Form1 created');
169166end;
170167
171168procedure TForm1.FormDestroy(Sender: TObject);
172169begin
173170 Logger.Send('Form1 destroyed');
174171end;
175172
176173procedure TForm1.Button1Click(Sender: TObject);
177174begin
178175 Logger.IncCounter('MyLogCounter');
179176end;
180177
181178procedure TForm1.Button2Click(Sender: TObject);
182179begin
183180 Logger.ResetCounter('MyLogCounter');
184181end;
185182
186183procedure TForm1.Button3Click(Sender: TObject);
187184begin
188185 Logger.Watch('MyLogWatch', Caption);
189186end;
190187
191188procedure TForm1.Button4Click(Sender: TObject);
192189var
193190 Exc: EMathError;
194191begin
195192 try
196193 Exc := EMathError.Create('fake math exception');
197194 raise Exc;
198195 except
199196 on E: Exception do Logger.SendException('Exception: Force fake math exception', E);
200197 end;
201198end;
202199
203200procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
204201begin
205202 Logger.Send('Panel1MouseDown');
206203end;
207204
208205procedure TForm1.Panel1MouseEnter(Sender: TObject);
209206begin
210207 Logger.Send('Panel1MouseEnter');
211208end;
212209
213210procedure TForm1.Panel1MouseLeave(Sender: TObject);
214211begin
215212 Logger.Send('Panel1MouseLeave');
216213end;
217214
218215procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
219216begin
220217 Logger.Send('Panel1MouseUp');
221218end;
222219
223220procedure TForm1.SpinEdit1Change(Sender: TObject);
224221begin
225222 Logger.EnterMethod('SpinEdit1Change');
226223 try
227224 Caption := 'New SpinEdit1 value is ' + IntToStr(SpinEdit1.Value);
228225 Logger.Send('SpinEdit1.Value', SpinEdit1.Value);
229226 finally // we want to make sure that each EnterMethod is paired with it's Exitmethod
230227 Logger.ExitMethod('SpinEdit1Change');
231228 end;
232229end;
233230
234231end.
235232```
236233
237234This is how the result should look like in runtime (if you replace default captions as shown):
238235
239-<figure>
240-<img src="MultiLogSimpleDemo.png" title="MultiLogSimpleDemo.png" />
241-<figcaption>MultiLogSimpleDemo.png</figcaption>
242-</figure>
236+![](/wiki-images/7/74/MultiLogSimpleDemo.png)
243237
244-<figure>
245-<img src="MultiLogViewerForSimpleDemo.png" title="MultiLogViewerForSimpleDemo.png" />
246-<figcaption>MultiLogViewerForSimpleDemo.png</figcaption>
247-</figure>
238+![](/wiki-images/4/45/MultiLogViewerForSimpleDemo.png)
248239
249240If 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'.
250241
251242### Known Issues
252243
253244- ~~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~~
254245 - ~~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.~~
255246 - ~~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.~~
256247- ~~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.~~
257248 - ~~Waiting for fpc2.2 to re-enable inline.~~
258249
259250### See also
260251
261252- [[doc:fcl/eventlog/teventlog.html|TEventLog documentation]] Built in support for logging in FPC/Lazarus
262253- [[LazLogger]] Logging support supplied with Lazarus
263254- [[log4delphi]] Another Lazarus logging framework ported from Delphi
264255
265256---
266257*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).*
267258Category: Components
268259Category: Lazarus
269260Category: Lazarus-CCR
270261Category: Logging

Back to history