Sign in Join
Wiki copytemporary

LazLogger: what changed

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

OldNewLine
11## Overview
22
33The unit **LazLogger** is supplied with Lazarus and provides logging to file or console.
44
55## Usage
66
77### Adding logging support to your source code
88
99By just including the unit **lazlogger** you can use the following:
1010
1111- **[[DebugLn]]:** which works about the same as WriteLn.
1212- **DebugLnEnter/DebugLnExit:** same as debugln, but DebugLnEnter increases (and DebugLnExit decreases) the indentation of the written line.
1313- **DbgOut:** which works about the same as Write.
1414
1515All of the above can be called with either:
1616
1717- A single string, or list of (up to 15) strings: DebugLn('Foo'); DbgOut('a','b');
1818- An array of const: DebugLn(\['Foo=', 1, ' Bar=', anInteger\]);
1919- Same arguments as Format(). String + array of const: DbgOut('a %d',\[1\]);
2020
2121Also there are many **dbgs** functions. Each converts a common type to a string for display. For example dbgs(aRect) converts a variable of type TRect to a string. You can write your own dbgs() functions for type conversions Lazarus does not provide, such as your custom records, which you can then use in DebugLn etc.
2222
2323#### Activate/Deactivate LazLogger by using the correct unit
2424
2525LazLogger provides 3 units for your "uses" clause
2626
2727LazLogger
2828Use this unit in your main program only. Using this unit activates the functionality of LazLogger.
2929
3030LazLoggerBase
3131Use this unit whenever you want to use DebugLn. What LazLoggerBase does depends on whether the unit LazLogger is used in any other unit of your application. If the LazLogger unit is **not** used, LazLoggerBase installs a "black hole" logger which discards all log messages. If LazLogger **is** used anywhere, then all units using LazLoggerBase will write the log messages as described under "Logging Output"
3232
3333LazLoggerDummy
3434This unit provides you with dummy DebugLn calls (and all other LazLogger functions). They are just calls to empty methods. This allows you to disable all logging in a unit, without the need to remove any debugln statement.
3535
3636### Logging output
3737
3838#### Stdout/Console
3939
40-By default the output created by `DebugLn` is written to the `stdout` device. The output is silently discarded if `stdout` is not open. On Windows this is the default behavior, if project type "Application" is used to create a Windows GUI application. To get a console alongside your Windows GUI application, you need to <b>uncheck</b> the option "Win32 gui application (-WG)" under Project options / Compiler options / Config and Target / Target specific options. Alternatively you can add {\$APPTYPE CONSOLE} at the top of your project .lpr file, or configure multiple "Build Modes" to control the -WG switch.
40+By default the output created by `DebugLn` is written to the `stdout` device. The output is silently discarded if `stdout` is not open. On Windows this is the default behavior, if project type "Application" is used to create a Windows GUI application. To get a console alongside your Windows GUI application, you need to uncheck the option "Win32 gui application (-WG)" under Project options / Compiler options / Config and Target / Target specific options. Alternatively you can add {\$APPTYPE CONSOLE} at the top of your project .lpr file, or configure multiple "Build Modes" to control the -WG switch.
4141
4242#### File
4343
4444Debug output can also be written to file. The initialization code of the logging unit
4545
4646- checks your program's command line parameters for **--debug-log=\<file\>** (In Lazarus: Run / Run Parameters / Command line parameters). On finding this parameter, any subsequent debug output is sent to \<file\>.
4747
4848
4949The param name can be changed with **DebugLogger.ParamForLogFileName:='--debug-log';** This property exists only if the unit LazLogger is used. (LazLoggerBase does not define this property)
5050
5151- If no '--debug-log' command line parameter has been given, it next checks if an operating system environment variable xxx_debuglog exists, where xxx is the program file name without extension. E.g. for Lazarus this would be lazarus_debuglog. If such an environment variable exists, it uses the file specified in that environment variable as file to receive debug output.
5252
5353Example: if you do:
5454
5555```dos
5656set lazarus_debuglog=c:\lazarus\debug.txt
5757```
5858
5959and run Lazarus, debug output will be written to c:\lazarus\debug.txt.
6060
6161#### Debug server
6262
6363Not available in LazLogger; see [[DebugServer]].
6464
6565### Log Groups
6666
6767You can add log groups.
6868
6969``` pascal
7070var MY_LOG_GROUP: PLazLoggerLogGroup;
7171
7272initialization
7373 MY_LOG_GROUP := DebugLogger.FindOrRegisterLogGroup('fancy_name_for_mylog' {$IFDEF MY_LOG_GROUP_ON_BY_DEFAULT} , True {$ENDIF} );
7474```
7575
7676In your code use
7777
7878``` pascal
7979debugln(MY_LOG_GROUP, 'log this text');
8080debugln(MY_LOG_GROUP, ['a=',a,' b=',b]); // a,b must be basic types: integer, byte, ansistring. See types available for "array of const"
8181```
8282
8383and to enable it call your app with
8484
8585```dos
8686--debug-enable=fancy_name_for_mylog
8787```
8888
8989--debug-enable= takes a comma separated list
9090
9191An already enabled group ( DebugLogger.FindOrRegisterLogGroup('grpname', True) ) can be disabled by specifying the group name with a minus.
9292
9393```dos
9494--debug-enable=-fancy_name_for_mylog
9595```
9696
9797The parameter name can be set via **DebugLogger.ParamForEnabledLogGroups='--debug-enable';**
9898
9999## Documentation
100100
101101For more features, see the unit itself and the LCL documentation.
102102
103103Using LazLogger/LazLoggerBase your code can access the DebugLogger instance. This offers some properties to fine tune logging.
104104
105105You can also write your own logger class and use it with LazLogger/Base.
106106
107107## Multithreading
108108
109109- **DebugLn** is thread safe, since Lazarus 2.0.
110110
111111
112112That is once the logger is created, see below
113113
114114Earlier versions of this text stated "since 1.0", but a further race condition was found and fixed for 2.0.
115115
116116- Calls to **DbgOut**, **DebugLnEnter**, **DebugLnExit** can be made from threads, but may not always format/indent the output correctly.
117117
118118- The creation/setup/destruction/configuration of the logger is **not thread-safe**, and must be done before threads are started.
119119
120120
121121Creation is usually done with the first "debugln" call, maybe just debugln('') passing an empty string before any multi threaded code. Any other LazLogger access will also trigger creation and, once done, its done for the whole application.
122122
123123But any properties (eg ParamForLogFileName) should be set before accessing the logger from threads.
124124
125125- Callback to events like OnDebugLn are made in each thread. The code in the callback must be thread-safe by itself.
126126
127127
128128Changing the property is NOT thread-safe
129129
130130## See also
131131
132132- [[doc:fcl/eventlog/teventlog.html|TEventLog documentation]] Built in support for logging in FPC/Lazarus
133133- [[DebugServer]] Allows sending log entries to a viewer via IPC
134134- [[MultiLog]]
135135- [[log4delphi]]
136136- The package IdeLazLogger, which adds a dialog to the IDE allowing to enable/disable log groups used in the IDE itself.
137137
138138---
139139*From the Free Pascal wiki, page "LazLogger", as it stood on 2024-05-26 after a change by Dbannon, 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).*
140140Category: Debugging
141141Category: LCL
142142Category: Lazarus
143143Category: Logging

Back to history