Last updated at 5:12 am UTC on 6 April 2009
The page title is potentially confusing. It should be called something like: "Logging Package" and not Logging, that could be viewed as the activity
This page is kinda out-of-date. The latest info is in this email from keith
Logging for squeak, a front end to Toothpick, SimpleLog or LogEngine
Installer install: 'Logging'
Installer universe install: 'Logging'; install.
Choose Your Backend
This is all out of date. the real way to do this is now:
LogCurrent default adapter add: Transcript; add: (LogFile named: 'my.log')
SimpleLog - simple and practical intro
Toothpick - (the mother of all logging frameworks) website
Null - For minimal images that wish to disable/remove logging altogether
LogTranscript - built in default
SimpleLog startFile: 'my.log'.
The above use this pattern to set the global logging policy with custom router.
CurrentLog default: (MyLogRouter use: Toothpick).
The default is the minimal LogTranscript.
To set the local per process logging policy:
CurrentLog value: (LogRouter use: SimpleLog).
You can customize the framework adapters by subclassing:
Subclasses of LogRouter are the simplest place for coders to configure logging policy, i.e. which messages are logged, and to which logging framework.
LogCurrent default: (MyLogRouterPolicy use: MySimpleLog).
Routers and Threads:
A routers instance is returned from self log in whatever context it is used. The router is instantiated on a per process basis, therefore I am threadsafe already, and can reuse my buffers and maintain state as we progress through the code which we are logging. Unusually for a logging framework this allows us to perform timing tasks for our clients. If the code forks then a new router instance will handle the new forked process.
For timing use:
self log timeTotal: #eventA. "a cumulative total"
self log timeDelta: #eventB. "a periodic timer"
Convenient usage: 'annotated values'
This uses the logging level defined by LogRouter-temp, and is considered a temporary log message for debugging purposes. For temporary log messages the specific level is rarely important. There is by default a global preference for disabling temporary log level messages. Of course your subclasses can override this behaviour.
self log x: 10 y: 20 z: 30.
To select a specific log severity level (i.e. not the temporary one featured above).
self log info x: 10 y: 20 z: 30.
To log the current method's input parameters.
Rectangle-#corner: topLeftPoint extent: heightWidthPoint
self log debug this.
would be similar to
self log corner: topLeftPoint extent: heightWidthPoint.
To report about the current instance:
self log it slots.
self log it all.
To obtain a stack trace
self log stack.
Levels of detail:
When logging it is useful to be able to specify easily the level of detail that we desire from the items we are given.
Here we define 4 levels of detail.
1. Annotated values: the data points are simple values intended to be displayed on one line.
The method selector is used to annotate the vaues for readability.
self log info r: 20 theta: 0.5.
2. Verbatim: Stream to the Log
(self log info << 'User Directory:' << aFilePath) write.
3. Detailed: human readable presentation: A detailed presentation of the objects internal state intended for human readability.
The detail printed is based upon the object's explorer contents, as defined in #logDetailedOn:
self log info detailed: myDictionary.
4. Data Dumper: A machine readable serialized text format.
The format printed is defined in #logDumperOn:
For those perl coders out there who really like being able to recreate their data from logs!
self log info dumper: myTransaction.
Roll Your Own Category
Frameworks may wish to define their own categories, e.g. #mysql #glorp #seaside etc. These are used as follows
self log error mysql query: q result: r. "or"
Frameworks that use Logging may reserve their own category name in LogRouter if they wish.
Optional Logging Code
To configure your own specialized logging policy subclass LogRouter, those messages that you do not wish to log, override to return self ignore.
If your logging code does a lot of work when preparing the data to output, it is possible to wrap it in a block as follows. This allows the block of code to be completely skipped over if the MyLogRouterPolicy sets a log level to ignore.
self log info mysql use: [ :log | log query: q result: r. ].
self log mysql use: [
self log info x: 1 y: 2.
self log this.