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

Get Adobe Flash player

 

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 )

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  3.     <mx:Script>
  4.         <![CDATA[
  5.             import org.osflash.thunderbolt.Logger;
  6.             import flash.events.Event;
  7.             private function traceToFirebug(event:Event):void
  8.             {
  9.                 var n: int = 5;
  10.                 var s: String = "Lorem ipsum";
  11.                 var o: Object = {exampleArray: ["firstValue", "secondValue"], y: 10, exampleString: "Hello", nestedObject: {x: 100, y: 200}};
  12.                 var a: Array = ["firstValue",{x: 100, y: 200}, "secondValue"];
  13.                 var label: String = event.target.label;
  14.                 switch (label)
  15.                 {
  16.                     case "info":
  17.                         Logger.trace ("i a simple string", s);
  18.                     break;
  19.                     case "error":
  20.                         Logger.trace ("i a number typed as int", n);
  21.                     break;
  22.                     case "warn":
  23.                         Logger.trace ("e an array with a nested object: ", a);
  24.                     break;
  25.                     case "debug":
  26.                         Logger.trace ("w an object with a nested object and nested array",o);
  27.                     break;
  28.                     default:
  29.                 }
  30.             }
  31.       ]]>
  32.     </mx:Script>
  33.     <mx:Style source="css/logger.css"/>
  34.     <mx:Text htmlText="Press F12 to open Firebug" paddingBottom="20"/>
  35.     <mx:HBox horizontalGap="10">
  36.          <mx:Button label="info"
  37.                     click="traceToFirebug(event);" id="infoButton" width="100" height="50"/>
  38.          <mx:Button label="error"
  39.                     click="traceToFirebug(event);" id="errorButton" width="100" height="50"/>
  40.          <mx:Button label="warn"
  41.                     click="traceToFirebug(event);" id="warnButton" width="100" height="50"/>
  42.          <mx:Button label="debug"
  43.                     click="traceToFirebug(event);" id="debugButton" width="100" height="50"/>
  44.     </mx:HBox>
  45. </mx:Application>

Source

First of all: Feel free to check out the latest source via SVN ;-) .

Logger.as ( Download code )

  1. /**
  2. * Logging Flex and AS3 projects with Firebug
  3. *
  4. * @author   Jens Krause [www.websector.de]
  5. * @date  04/21/07
  6. * @see  http://www.websector.de/blog/2007/04/21/logging-flex-2-and-as-3-apps-with-firebug-and-thunderbolt/
  7. * @source   http://flash-thunderbolt.googlecode.com/svn/trunk/as3/
  8. *
  9. */
  10. package org.osflash.thunderbolt
  11. {
  12.     import flash.external.ExternalInterface;
  13.     import flash.utils.describeType;
  14.     import flash.utils.getQualifiedClassName;
  15.     import flash.utils.getDefinitionByName;
  16.     /**
  17.     *
  18.     */
  19.     public class Logger
  20.     {
  21.         public static const LOG: String = "log";
  22.         public static const INFO: String = "info";
  23.         public static const WARN: String = "warn";
  24.         public static const ERROR: String = "error";
  25.         private static const MAX_DEPTH: int = 255;
  26.         private static var depth: int;
  27.         private static var logLevel: String;
  28.         /**
  29.          * Calls Firebugs command line API to write log information
  30.          *
  31.          * @param   msg   log Message
  32.          * @param   obj   log object
  33.          */
  34.         public static function trace (msg: String = null, obj:Object = null): void
  35.         {
  36.             depth = 0;
  37.             //
  38.             // log description
  39.             logLevel = (msg != null) ? Logger.getLogLevel(msg) : Logger.LOG;
  40.             var txtMessage: String = (msg != null && msg.length>= 3) ? msg.slice(2) : "";
  41.             var logMsg: String = logLevel.toUpperCase() + ": " + txtMessage;
  42.             ExternalInterface.call("console." + logLevel, logMsg);
  43.             //
  44.             // log object
  45.             if (obj) Logger.logProperties(obj);
  46.         }
  47.         /**
  48.          * Logs nested instances and properties
  49.          *
  50.          * @param   logObj  log object
  51.          * @param   id    short description of log object
  52.          */
  53.         private static function logProperties (logObj: *, id: String = null): void
  54.         {
  55.             ++ depth;
  56.             var propID: String = id || "";
  57.             if (depth <Logger.MAX_DEPTH)
  58.             {
  59.                 var description:XML = describeType(logObj);
  60.                 var type: String = description.@name;
  61.                 if (primitiveType(type))
  62.                 {
  63.                     var msg: String = (propID.length)   ?    "[" + type + "] " + propID + " = " + logObj
  64.                                                         :   "[" + type + "] " + logObj;
  65.                     ExternalInterface.call("console." + Logger.LOG, msg);
  66.                 }
  67.                 else if (type == "Object")
  68.                 {
  69.                     ExternalInterface.call("console.group", "[Object] " + propID);
  70.                     for (var element: String in logObj)
  71.                     {
  72.                       logProperties(logObj[element], element);
  73.                     }
  74.                     ExternalInterface.call("console.groupEnd");
  75.                 }
  76.                 else if (type == "Array")
  77.                 {
  78.                     ExternalInterface.call("console.group", "[Array] " + propID);
  79.                     for (var i: int = 0; i <logObj.length; i++)
  80.                     {
  81.                       logProperties(logObj[i]);
  82.                     }
  83.                     ExternalInterface.call("console.groupEnd");
  84.                 }
  85.                 else
  86.                 {
  87.                     var list: XMLList = description..variable;
  88.                     if (list.length())
  89.                     {
  90.                         for each(var item: XML in list)
  91.                         {
  92.                             var propItem: String = item.@name;
  93.                             var typeItem: String = item.@type;
  94.                             // var ClassReference: Class = getDefinitionByName(typeItem) as Class;
  95.                             var valueItem: * = logObj[propItem];
  96.                             logProperties(valueItem, propItem);
  97.                         }
  98.                     }
  99.                     else
  100.                     {
  101.                         logProperties(logObj, type);
  102.                     }
  103.                 }
  104.             }
  105.             else
  106.             {
  107.                 ExternalInterface.call("console." + Logger.WARN, "STOP LOGGING: More than " + depth + " nested objects or properties");
  108.             }
  109.         }
  110.         /**
  111.          * Checking for primitive types
  112.          *
  113.          * @param   type        type of object
  114.          * @return  isPrimitiveType  isPrimitiveType
  115.          *
  116.          */
  117.         private static function primitiveType (type: String): Boolean
  118.         {
  119.             var isPrimitiveType: Boolean;
  120.             switch (type)
  121.             {
  122.                 case "Boolean":
  123.                     isPrimitiveType = true;
  124.                 break;
  125.                 case "void":
  126.                     isPrimitiveType = true;
  127.                 break;
  128.                 case "int":
  129.                     isPrimitiveType = true;
  130.                 break;
  131.                 case "uint":
  132.                     isPrimitiveType = true;
  133.                 break;
  134.                 case "Number":
  135.                     isPrimitiveType = true;
  136.                 break;
  137.                 case "String":
  138.                     isPrimitiveType = true;
  139.                 break;
  140.                 case "undefined":
  141.                     isPrimitiveType = true;
  142.                 break;
  143.                 case "null":
  144.                     isPrimitiveType = true;
  145.                 break;
  146.                 default:
  147.                     isPrimitiveType = false;
  148.             }
  149.             return isPrimitiveType;
  150.         }
  151.         /**
  152.          * Translates log keys to Firebug log levels,
  153.          * which based on zeroi’s key mapping
  154.          * @see  http://www.osflash.org/zeroi/
  155.          *
  156.          * @param   msg
  157.          * @return  level description
  158.          *
  159.          */
  160.         private static function getLogLevel (msg: String): String
  161.         {
  162.             var firstChar: String = (msg.charAt(1) == " ") ? msg.charAt(0).toLowerCase() : "d";
  163.             var level: String;
  164.             switch (firstChar)
  165.             {
  166.                 case "i":
  167.                     level = Logger.INFO;
  168.                 break;
  169.                 case "w":
  170.                     level = Logger.WARN;
  171.                 break;
  172.                 case "e":
  173.                     level = Logger.ERROR;
  174.                 break;
  175.                 case "d":
  176.                     level = Logger.LOG;
  177.                 break;
  178.                 default:
  179.                     level = Logger.LOG;
  180.             }
  181.             return level;
  182.         }
  183.     }
  184. }

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.

Related Articles

3 Responses to “Logging Flex 2 and AS 3 apps with Firebug and ThunderBolt”

  1. Brian Lai Says:

    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);

  2. sectore Says:

    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/

  3. WS-Blog » 10 tips and tricks using ThunderBolt AS3 Says:

    [...] 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. [...]

Leave a Reply

Follow sectore on Twitter