Creating a custom logging target
The birth of LumberJack

I figured since I'm on the subject I would go ahead and share my code for creating your own custom logging target, called LumberJack. This particular target sends log message objects over a LocalConnection to a basic logging console that will output them into a text field. This tool can be a life saver and is one that I plan to continue to develop. Being able to see trace statements from a site running on any server, on any network can really help when debugging your application that is deployed somewhere besides your localhost. There are other tools out there that do this like RED|Bug, but this one is extremely simple and includes all the code so you can modify it to suit your needs.

First let's create the new log target class by extending the existing mx.logging.targets.LineFormattedTarget Flex class. Then override the logEvent method with the functionality desired and you're in business. Here's how I did it:

package {
    import flash.events.StatusEvent;
    import flash.events.AsyncErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.LocalConnection;
    import mx.logging.LogEvent;
    import mx.logging.targets.LineFormattedTarget;
    import mx.utils.ObjectUtil;

    public class LogMessageDispatcherTarget extends LineFormattedTarget {
        private var _conn:LocalConnection;
        
        public function LogMessageDispatcherTarget() {
            super();
            _conn = new LocalConnection();
            _conn.addEventListener(StatusEvent.STATUS, onStatus);
            _conn.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
            _conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
        }
        
        override public function logEvent(event:LogEvent):void {
            _conn.send("echo1","update",{level:event.level,category:event.currentTarget.category,message:event.message,time:this.includeTime});
        }
        
        //since these methods deal with LocalConnection errors we have to trace them.
        private function onStatus(evt:StatusEvent):void {
            trace("onStatus Event: "+ObjectUtil.toString(evt));
        }
        
        private function onAsyncError(evt:AsyncErrorEvent):void {
            trace("onAsyncError Event: "+ObjectUtil.toString(evt));
        }
        
        private function onSecurityError(evt:SecurityErrorEvent):void {
            trace("onSecurityError Event: "+ObjectUtil.toString(evt));
        }
    }
}


Building on the previous post, I have swapped out the TraceTarget for our new LogMessageDispatcherTarget.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init();">
    <mx:Script>
        <![CDATA[
            import mx.logging.Log;
            import mx.logging.ILogger;
            import mx.logging.LogEventLevel;
            import LogMessageDispatcherTarget;
            
            private var _log:ILogger;
            private var _loggerTarget:LogMessageDispatcherTarget;
            
            private function init():void {
                _loggerTarget = new LogMessageDispatcherTarget();
                _loggerTarget.filters=["*"];
                _loggerTarget.level = LogEventLevel.ALL;
                _loggerTarget.includeDate = false;
                _loggerTarget.includeTime = false;
                _loggerTarget.includeCategory = true;
                _loggerTarget.includeLevel = true;
                Log.addTarget(_loggerTarget);
                
                _log = Log.getLogger("ExampleRemoteLogger");
                _log.info("Logging rocks, Yo!");
            }
        ]]>
    </mx:Script>
</mx:Application>


The only thing missing now is the LumberJack console to receive and output the log messages. I won't go into it's implementation here, but you can download the Flex project. There will be more additions to LumberJack, such as message filtering, color coding and buffered output for improved performance. Check back for updates.

Comments are closed.