Logging Flex 2 and AS 3 apps with Firebug and ThunderBolt
April 21st, 2007
A few weeks ago Martin Kleppe started a project on Google Code called Flash-ThunderBolt. The idea behind based on Manfred Webers blog entry “Make MTASC talk to Firebug” which describes a way for logging Flash apps compiled with MTASC using Firebug.
I’ve already joined the Flash-Thunderbolt project for coding an AS3 version. It won’t be a copy of the current AS2 package but rather another approach for using Firebugs Console API as simple as possible. Check it out, here are my first steps:
Example
Instructions
The ThunderBolt AS3 package contains only one class named Logger.as. It supports logging primitive types such as Number, String, Boolean, etc. as well as Objects, Arrays and public properties of all classes. Use short cuts for determing different log levels as Zeroi does: “i” = info, “e” = error, “w” = warn, “d” = debug.
Here is an example:
ThunderBoltAS3Example.mxml ( Download code )
-
<?xml version="1.0" encoding="utf-8"?>
-
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
-
<mx:Script>
-
<![CDATA[
-
import org.osflash.thunderbolt.Logger;
-
import flash.events.Event;
-
private function traceToFirebug(event:Event):void
-
{
-
var n: int = 5;
-
var s: String = "Lorem ipsum";
-
var o: Object = {exampleArray: ["firstValue", "secondValue"], y: 10, exampleString: "Hello", nestedObject: {x: 100, y: 200}};
-
var a: Array = ["firstValue",{x: 100, y: 200}, "secondValue"];
-
var label: String = event.target.label;
-
switch (label)
-
{
-
case "info":
-
Logger.trace ("i a simple string", s);
-
break;
-
case "error":
-
Logger.trace ("i a number typed as int", n);
-
break;
-
case "warn":
-
Logger.trace ("e an array with a nested object: ", a);
-
break;
-
case "debug":
-
Logger.trace ("w an object with a nested object and nested array",o);
-
break;
-
default:
-
}
-
}
-
]]>
-
</mx:Script>
-
<mx:Style source="css/logger.css"/>
-
<mx:Text htmlText="Press F12 to open Firebug" paddingBottom="20"/>
-
<mx:HBox horizontalGap="10">
-
<mx:Button label="info"
-
click="traceToFirebug(event);" id="infoButton" width="100" height="50"/>
-
<mx:Button label="error"
-
click="traceToFirebug(event);" id="errorButton" width="100" height="50"/>
-
<mx:Button label="warn"
-
click="traceToFirebug(event);" id="warnButton" width="100" height="50"/>
-
<mx:Button label="debug"
-
click="traceToFirebug(event);" id="debugButton" width="100" height="50"/>
-
</mx:HBox>
-
</mx:Application>
Source
First of all: Feel free to check out the latest source via SVN
.
Logger.as ( Download code )
-
/**
-
* Logging Flex and AS3 projects with Firebug
-
*
-
* @author Jens Krause [www.websector.de]
-
* @date 04/21/07
-
* @see http://www.websector.de/blog/2007/04/21/logging-flex-2-and-as-3-apps-with-firebug-and-thunderbolt/
-
* @source http://flash-thunderbolt.googlecode.com/svn/trunk/as3/
-
*
-
*/
-
package org.osflash.thunderbolt
-
{
-
import flash.external.ExternalInterface;
-
import flash.utils.describeType;
-
import flash.utils.getQualifiedClassName;
-
import flash.utils.getDefinitionByName;
-
/**
-
*
-
*/
-
public class Logger
-
{
-
public static const LOG: String = "log";
-
public static const INFO: String = "info";
-
public static const WARN: String = "warn";
-
public static const ERROR: String = "error";
-
private static const MAX_DEPTH: int = 255;
-
private static var depth: int;
-
private static var logLevel: String;
-
/**
-
* Calls Firebugs command line API to write log information
-
*
-
* @param msg log Message
-
* @param obj log object
-
*/
-
public static function trace (msg: String = null, obj:Object = null): void
-
{
-
depth = 0;
-
//
-
// log description
-
logLevel = (msg != null) ? Logger.getLogLevel(msg) : Logger.LOG;
-
var txtMessage: String = (msg != null && msg.length>= 3) ? msg.slice(2) : "";
-
var logMsg: String = logLevel.toUpperCase() + ": " + txtMessage;
-
ExternalInterface.call("console." + logLevel, logMsg);
-
//
-
// log object
-
if (obj) Logger.logProperties(obj);
-
}
-
/**
-
* Logs nested instances and properties
-
*
-
* @param logObj log object
-
* @param id short description of log object
-
*/
-
private static function logProperties (logObj: *, id: String = null): void
-
{
-
++ depth;
-
var propID: String = id || "";
-
if (depth <Logger.MAX_DEPTH)
-
{
-
var description:XML = describeType(logObj);
-
var type: String = description.@name;
-
if (primitiveType(type))
-
{
-
var msg: String = (propID.length) ? "[" + type + "] " + propID + " = " + logObj
-
: "[" + type + "] " + logObj;
-
ExternalInterface.call("console." + Logger.LOG, msg);
-
}
-
else if (type == "Object")
-
{
-
ExternalInterface.call("console.group", "[Object] " + propID);
-
for (var element: String in logObj)
-
{
-
logProperties(logObj[element], element);
-
}
-
ExternalInterface.call("console.groupEnd");
-
}
-
else if (type == "Array")
-
{
-
ExternalInterface.call("console.group", "[Array] " + propID);
-
for (var i: int = 0; i <logObj.length; i++)
-
{
-
logProperties(logObj[i]);
-
}
-
ExternalInterface.call("console.groupEnd");
-
}
-
else
-
{
-
var list: XMLList = description..variable;
-
if (list.length())
-
{
-
for each(var item: XML in list)
-
{
-
var propItem: String = item.@name;
-
var typeItem: String = item.@type;
-
// var ClassReference: Class = getDefinitionByName(typeItem) as Class;
-
var valueItem: * = logObj[propItem];
-
logProperties(valueItem, propItem);
-
}
-
}
-
else
-
{
-
logProperties(logObj, type);
-
}
-
}
-
}
-
else
-
{
-
ExternalInterface.call("console." + Logger.WARN, "STOP LOGGING: More than " + depth + " nested objects or properties");
-
}
-
}
-
/**
-
* Checking for primitive types
-
*
-
* @param type type of object
-
* @return isPrimitiveType isPrimitiveType
-
*
-
*/
-
private static function primitiveType (type: String): Boolean
-
{
-
var isPrimitiveType: Boolean;
-
switch (type)
-
{
-
case "Boolean":
-
isPrimitiveType = true;
-
break;
-
case "void":
-
isPrimitiveType = true;
-
break;
-
case "int":
-
isPrimitiveType = true;
-
break;
-
case "uint":
-
isPrimitiveType = true;
-
break;
-
case "Number":
-
isPrimitiveType = true;
-
break;
-
case "String":
-
isPrimitiveType = true;
-
break;
-
case "undefined":
-
isPrimitiveType = true;
-
break;
-
case "null":
-
isPrimitiveType = true;
-
break;
-
default:
-
isPrimitiveType = false;
-
}
-
return isPrimitiveType;
-
}
-
/**
-
* Translates log keys to Firebug log levels,
-
* which based on zeroi’s key mapping
-
* @see http://www.osflash.org/zeroi/
-
*
-
* @param msg
-
* @return level description
-
*
-
*/
-
private static function getLogLevel (msg: String): String
-
{
-
var firstChar: String = (msg.charAt(1) == " ") ? msg.charAt(0).toLowerCase() : "d";
-
var level: String;
-
switch (firstChar)
-
{
-
case "i":
-
level = Logger.INFO;
-
break;
-
case "w":
-
level = Logger.WARN;
-
break;
-
case "e":
-
level = Logger.ERROR;
-
break;
-
case "d":
-
level = Logger.LOG;
-
break;
-
default:
-
level = Logger.LOG;
-
}
-
return level;
-
}
-
}
-
}
Feedback
Feedback and suggestions for improvement are welcome
If you’d like to join the Flash-ThunderBolt project just drop me an email or feel free to post a comment.



May 23rd, 2007 at 1:53 am
I factored function “trace” and made it look more like the Java way:
…
public static function trace (msg: String = null, obj:Object = null): void
{
depth = 0;
//
// log description
logLevel = (msg != null) ? Logger.getLogLevel(msg) : Logger.LOG;
var txtMessage: String = (msg != null && msg.length>= 3) ? msg.slice(2) : “”;
doTrace(logLevel, msg, obj);
}
private static function doTrace (level:String, msg:String, obj:Object):void {
var logMsg: String = level.toUpperCase() + “: ” + msg;
ExternalInterface.call(“console.” + level, logMsg);
//
// log object
if (obj) Logger.logProperties(obj);
}
public static function info (msg:String = null, obj:Object = null):void {
depth = 0;
doTrace(INFO, msg, obj);
}
public static function warn (msg:String = null, obj:Object = null):void {
depth = 0;
doTrace(WARN, msg, obj);
}
public static function log (msg:String = null, obj:Object = null):void {
depth = 0;
doTrace(LOG, msg, obj);
}
public static function error (msg:String = null, obj:Object = null):void {
depth = 0;
doTrace(ERROR, msg, obj);
}
…
======================================================
Usage:
Logger.info(message:String, object:Object);
Logger.warn(message:String, object:Object);
Logger.error(message:String, object:Object);
Logger.log(message:String, object:Object);
June 21st, 2007 at 11:24 am
Brain,
thanks for your hint – I’ve updated the ThunderBolt AS3 package based on your comment
Check it out:
http://www.websector.de/blog/2007/06/20/update-part-2-logging-flex-2-and-as3-applications-with-firebug-and-thunderbolt/
June 15th, 2008 at 5:15 pm
[...] Almost one year ago I started to develop a small extension called ThunderBolt AS3 for logging ActionScript 3 applications using Firebug as simple as possible. Today its nice to see that the community uses and supports this extension as well. [...]