A problem occured while loading the plugin: krl_flickr_photoset -> : Assigning the return value of new by reference is deprecated on line 18
kelvinluck.com: Logging from FAME
Get Firefox! creative commons

Logging from FAME

I’ve recently started playing with FAME (or more properly FME – FDT, MTASC and Eclipse) and found it frustrating not having a trace window in Eclipse which I could use to debug my code…

Then I discovered Powerflasher SOS which is a handy standalone console which you can connect to via an XMLSocket from Flash. SOS has some incredible handy features for use along with FME. For example you can set it to “Console > Bring to Front > During Connection”. This means that the logging console will stay at the front of your screen while there is a socket connection open to it. I found it fiddly with other logging solutions which had a console opening within a panel in Eclipse (maybe because of the lack of screen real estate on my laptop). So I like this feature a lot. You could even run the SOS console on a different machine to make maximum use of screen space!

I thought what if I could combine the power of SOS with the convenient object introspection of the LuminicBox logger and colour coding etc.. And while I was at it I decided to also add support for the MTASC TRACE directive. So I did. Building on the TracePublisher from LuminicBox and adjusting a little code I came up with something which turns this:

* example code for using a com.kelvinluck.util.SOSLogPublisher

import com.kelvinluck.util.SOSLogPublisher;
import com.kelvinluck.util.LogWrapper;

LogWrapper.getLog().addPublisher(new SOSLogPublisher("myAppsName"));
// log messages at different levels
LogWrapper.getLog().fatal("This is a fatal error :'(");
LogWrapper.getLog().error("This is an error :(");
LogWrapper.getLog().warn("This is a warning, warning, warning");
LogWrapper.getLog().info("This is information");
LogWrapper.getLog().debug("This is debugging info");
// an Array (folded by default in SOS)
LogWrapper.getLog().debug([1,2,3,{a:"Part A", b:"Part B"}, "Some text", 99]);
// an anoynomous object (also folded by default)
LogWrapper.getLog().error({a:"this is a", b:"and this is b"});
// an object with a toString method (folded by default with the name from the toString method shown)...
var testObj:Foo = new Foo("bar", 2000, ["A", "B", "C", "DDDDDD"]);
// and using TRACE - add "-trace com.kelvinluck.util.LogWrapper.mtascTrace" to the commandline and compile using MTASC
trace("Check out the class and line number info above!");
trace({error:"something is wrong"}, LogWrapper.ERROR);

Into this (showing the horizontal scrollbar and four objects – three in their default folded states and one which I have “unfolded”):

SOS in action

If you want to play with this code please feel free to download it here.

The zip file includes an example class with a static main method that can be used to test the installation.

To use these classes successfully you will need a couple of things:

Powerflasher SOS – install it and run it. Select “Console > Bring to Front > During Connection” from the menu.

LuminicBox logger – install the extension. I have also included the LuminicBox classes in my zip just because I had to make a few tiny changes to get them to play nice with MTASC which is stricter than the MMC.

Unfortunately SOS only runs on windows so at least the machine that you view the logs on must be a windows machine.

You can use it pretty much as demonstrated by the code above… Also check in the comments to the SOSLogPublisher code to see the arguments you can pass to the constructor etc… Just make sure that the relevant files are in your classpath.

If you are using these files along with MTASC’s trace functionality then you will need to add the following argument to your command line to MTASC:

-trace com.kelvinluck.util.LogWrapper.mtascTrace

Also note that you can do the following to toggle the display of line numbers:

LogWrapper.logCallingFile = false; // stops class / file / line number information from being logged
LogWrapper.logCallingFile = true; // starts class / file / line number information getting logged.

If you are using in with FDT then I found it really useful to create 4 Templates (“Window > Preferences > FDT > Templates > Templates”) to speed up entering debug code. For example, I have the “ze” (without the quotes) mapped to:


or if you are using MTASC and trace you may find this more useful:

trace(${cursor}, LogWrapper.ERROR)

And similarly for the other log levels.

When you publish your finished file for production you can simply comment out the relevant addPublisher line to you don’t need to worry about the innards of your program being visible to others. Or if you use MTASC and trace then even better – just change the trace argument to be ”-trace no” and the traces won’t even be compiled into your final swf!

2005-08-30: First release
2005-08-31: Added folding so that Objects, Arrays etc which are logged are folded by default and can be opened inside SOS if you desire.
2005-09-01: Bug fix so XML and other objects containing < and > can be debugged.
2005-09-01: Added support for MTASC’s TRACE command
2005-09-10: Wrapped traced data in CDATA block so that ampersands, <'sand >’s can be successfully debugged.
2005-09-14: Added Natural Docs to the download zip.

If you find this useful or can think of a way that it can be more useful then please let me know below by leaving a comment below or via the OSFlash mailing list.

  1. Hi Kelvin,

    Great job,.. I did the same last week for a as2lib SosHandler, except of code folding what would have been the next point on my todo list ;-). Would you mind if I take over parts of your code into the as2lib SosHandler, (object inspection, folding,..) not have to do the same job again? =). Of course you would be mentioned as author incode.


    Christoph Atteneder    Sep 11, 07:05    #
  2. Hi Christoph,

    Glad you like it. Feel free to use parts of the code in as2lib :) None of it is rocket science! The object inspection code is basically from LuminicBox Logger so retain the credit to that as well…


    Kelvin :)
    Kelvin    Sep 11, 10:49    #
  3. hey thanks, very useful.
    btw, ‘TRACE’ became ‘trace’ in MTASC 1.10
    Raz-L    Sep 14, 11:09    #
  4. Glad you like it :)

    I’ve updated the code above to reference trace instead of TRACE – thanks for the headsup :)
    Kelvin    Sep 16, 19:23    #
  5. Ok, in trying to figure out a solution to our logging, I took a look at this solution. I’m not sure things are working quite as you suspect they are. I’m using the wrapper to initiate and establish a connection to SOS as you describe, however:

    LogWrapper.getLog().addPublisher(new SOSLogPublisher(“myAppsName”));

    does not establish a publisher through your wrapper… am I missing something?

    It doesn’t appear as though you ever use the .addConsolePublisher or .addTracePublisher functions that you built into your utility class. getLog() returns a logger, so I imported LuminicBox.Log.Logger and set a static var equal to LogWrapper.getLog() to clean up some of my code, but I noticed that when I’m adding publishers I’m actually doing so through the LuminicBox classes.
    — Ryan    Nov 9, 05:02    #
  6. Hi,

    Not sure where your confusion lies… The line:

    LogWrapper.getLog().addPublisher(new SOSLogPublisher(“myAppsName”));

    Adds a new SOSLogPublisher to the LuminicBox Log instance. The point of the LogWrapper class is just to make sure that their is only one Log instance and that you can always refer to the same Log instance from anywhere in your application (it is a Singleton)...

    The addConsolePublisher and addTracePublisher functions are just helper functions to add a LuminicBox ConsolePublisher (e.g. through LocalConnection to the “FlashInspector” swf) or TracePublisher (e.g. to the Flash IDE’s output panel). You could write a LogWrapper.addSOSLogPublisher function that looked like this if you liked:

    public function addSOSPublisher(appName:String, sosServer:String, sosPort:Number, maxDepth:Number)
    _log.addPublisher(new com.kelvinluck.util.SOSLogPublisher(appName, sosServer, sosPort, maxDepth));

    The end result is still the same – the SOSLogPublisher is added to the Log instance…

    Or do you mean that when you call:

    LogWrapper.getLog().error(“MY ERROR MESSAGE”);

    after the above initalisation nothing appears in your copy of SOS? If so, do you get any errors? Are you doing:

    import com.kelvinluck.util.SOSLogPublisher;

    At the top of your class?

    Hope that helps :)
    Kelvin    Nov 9, 10:32    #