In these days I played with Flex’s logging framework and I extended it to write log messages to files, both plain text .log files and dynamic HTML, CSS formatted and Javascript powered files with the ability to filter message type (debug, error, fatal and so on).
The logging framework is a powerful feature that comes with Flex’s sdk and it’s composed by the classes under mx.logging package, which includes the two “subpackages” mx.logging.errors and mx.logging.target.
Java developers should be already confident whit such framework, because logging api are commonly used in Java programming, Actionscript /Flash/Flex developers may find this tool a novelty (as I did).
The objective of logging framework is to provide a tool that offers a far better, flexible and centralized way to debug an application than simple use a lot of trace() callings. With Flex’s debugging framework we are able to print and filtering among different types of message based on their severity, such:
- DEBUG
- ERROR
- FATAL
- INFO
- WARN
We can also print the timestamp of the message and the class it refers to, and finally we can simultaneously print messages to different targets.
How it works
The logging framework is basically represented by 3 units: a logger, a target and a log event. The first component is the main class of the framework and its job is to register the different “loggable classes”, register one or more targets and dispatch log events. A target is a class which receives a LogEvent event and handles it by printing its information (message, date, level…) somewhere. A LogEvent event is dispatched when one of the logger methods such: debug(), error(), fatal(), info(), log() or warn() is called.
The steps required to use the logging system are the following:
1. Registering the classes for logging:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package com.daveoncode { import mx.logging.*; public class Foo { private var _logger:ILogger; public function Foo() { this._logger = Log.getLogger("com.daveoncode.Foo"); this._logger.debug("debugging message from Foo class"); this._logger.warn("warning message from Foo class"); } } } |
The code above will register the class Foo under the package com.daveoncode and then it will broadcast a debug and a warning message
2. Initialize and configure a logging target such TraceTarget (typically in the main class):
1 2 3 4 5 6 7 8 9 10 11 12 13 | var basicTarget:TraceTarget = new TraceTarget(); // Apply filters basicTarget.filters = ["com.daveoncode.*"]; // Log all log levels. basicTarget.level = LogEventLevel.ALL; // Add date, time, category, and log level to the output basicTarget.includeDate = true; basicTarget.includeTime = true; basicTarget.includeCategory = true; basicTarget.includeLevel = true; |
The code above will print log messages of all “subscribed” classes inside the package com.daveoncode, including all information available (date, time, category, level)
3. Add the target to the logger:
1 | Log.addTarget(basicTarget); |
The previous steps can be repeated as many times as we need, in order to registering several classes and several targets (perhaps with different filters and info settings).
How to extend the framework
To extend the framework we can create new target classes, which print LogEvent data to different location and display data as we like. In my experiment I created a “mini subframework” which can print logs to text files or html files. I created the following 7 classes:
- LogFileTarget
- IStreamDataWriter
- AbstractDataWriter
- PlainTextDataWriter
- HTMLDataWriter
- InvalidLogFileTargetError
- UnsupportedWriteModeError
The first, as the name suggest is a custom target class, which extends LineFormattedTarget (a target class available in Flex’s framework), it has a parametric constructor which allows the user to choose the name of the file, its directory, the type of file (txt or html) and the charset that will be used to write the file. IStreamDataWriter is an interface which simply declares one method called writeData(), the main purpose of this interface is to use it in polymorphism. IStreamDataWriter is implemented by AbstractDataWriter as an abstract method (abstract is not supported yet in as3, but is treated as abstract), this class also has a secondary method which is used by two subclasses PlainTextDataWriter and HTMLDataWriter. These classes have the duty to physically write data to the file by handling the event received by LogFileTarget which delegates the business logic to them and are used based on the writeMode configuration of LogFileTarget, which for ease has two public constants called MODE_PLAIN_TEXT and MODE_HTML. InvalidLogFileTargetError and UnsupportedWriteModeError are obviously two custom error which are both (potentially) thrown by LogFileTarget.
This is a sample code using my own classes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // this will print to an html file var HTMLTarget:LogFileTarget = new LogFileTarget("applicationLog", File.desktopDirectory, LogFileTarget.MODE_HTML); // this will print to a txt file var txtTarget:LogFileTarget = new LogFileTarget("applicationLog", File.desktopDirectory, LogFileTarget.MODE_PLAIN_TEXT); HTMLTarget.filters = ["*"]; // Log all log levels. HTMLTarget.level = LogEventLevel.ALL; // Add date, time, category, and log level to the output. HTMLTarget.includeDate = true; HTMLTarget.includeTime = true; HTMLTarget.includeCategory = true; HTMLTarget.includeLevel = true; txtTarget.filters = ["*"]; // Log all log levels. txtTarget.level = LogEventLevel.ALL; // Add date, time, category, and log level to the output. txtTarget.includeDate = true; txtTarget.includeTime = true; txtTarget.includeCategory = true; txtTarget.includeLevel = true; // Add targets Log.addTarget(HTMLTarget); Log.addTarget(txtTarget); |
Of course this experiment will works only in AIR applications, because we need to use flash.fileystem classes.
These are the two different output that my classes will generate:
Text file
HTML file
The cool aspect of html version (LogFileTarget.MODE_HTML) is that you can filter by log type :)
If you want to use or take a look to my experiment, feel free to download my logging package here (let me know your opinion)


October 20th, 2009 4:07 am
Hi good stuff, however the download link is not working. Thanks
October 20th, 2009 5:20 am
thank you for the catch, I fixed the link ;)
October 20th, 2009 6:27 am
thanks man – very nice stuff
October 20th, 2009 6:31 am
Actually your logging package is missing in the download
November 26th, 2009 4:58 pm
You should publish your source code. Github. :)
September 15th, 2010 8:47 am
I agree, you should publish your source code. Great article though.
October 14th, 2010 11:49 pm
Great article
November 21st, 2010 4:09 am
I’ve recently started a blog, the information you provide on this site has helped me tremendously. Thank you for all of your time & work.
November 25th, 2010 5:01 am
Hi,
This is very good one. can i get your source ,Please send mail me.
Thanks,
Raja
December 22nd, 2010 5:38 am
It is very helpfull, Thank you.
January 18th, 2011 7:53 am
Hi
Can we use another File class to use this swc with Flex Web App?
February 14th, 2011 10:46 am
HI ,
Looks awesome, but i dont see any source in attached link . please add a source to it or email me.
Thanks
March 11th, 2011 4:17 pm
Very nice article.. Can you publish entire source too..
Thanks.
-vm
April 5th, 2011 11:22 pm
Nice article. Please publish source code. It will be really helpful.
Thanks
-Miral
May 29th, 2011 10:50 am
Nice stuff. Can I get all the sources?