Creating a Database-backed Logging Target using AirDB

I've been using AirDB lately for one of my projects.  It's a nice, lightweight  Active Record implementation in ActionScript for use in Adobe Air applications.  I wanted to create a LogTarget for logging with the standard Flex logging framework (mx.logging) that was backed by a database.  

First, my AirDB domain object, LogEntry.as:

package {
   import com.memamsa.airdb.Modeler;
   import com.memamsa.airdb.Migrator;
   import com.memamsa.airdb.DB;

   public class LogEntry extends Modeler {
		
      public function LogEntry() {
         super();
      }
		
      private static const migrations:Migrator = new Migrator(
         LogEntry,
         {id: true},
         [
	    function(migrator:Migrator):void {
	       migrator.createTable(function():void {
                  migrator.column('level', DB.Field.Text, {allowNull: true});
                  migrator.column('message', DB.Field.Text, {allowNull: true});
	       });
            }
      	 ]);
      }
}

Now, for a log target that utilizes the domain object, DBLoggingTarget.as:

package {

   import mx.core.mx_internal;
   import mx.logging.LogEventLevel;
   import mx.logging.targets.LineFormattedTarget;
   use namespace mx_internal;

   public class DBLoggingTarget extends LineFormattedTarget {
 
      public function DBLoggingTarget() {
         super();
      }
 
      override mx_internal function internalLog(message:String):void {
         var logEntry:LogEntry = new LogEntry();
         var levelName:String;
         switch (level) {
            case LogEventLevel.WARN: {
               levelName = "WARN";
            }
            case LogEventLevel.INFO: {
               levelName = "INFO";
            }
            case LogEventLevel.FATAL: {
               levelName = "FATAL";
            }
            case LogEventLevel.ERROR: {
               levelName = "ERROR";
            }
            case LogEventLevel.DEBUG: {
               levelName = "DEBUG";
            }
            case LogEventLevel.ALL: {
               levelName = "ALL";
            }
         }
         logEntry.create({
            level: levelName,
            message: message
         });
      }
   }
}

Now to utilize this we only need:

DB.initDB("myDatabaseName.sqlite");
var logTarget:ILoggingTarget = new DBLoggingTarget();
logTarget.level = LogEventLevel.ERROR;
Log.addTarget(logTarget);

Or, if you are like me and use the wonderful Mate framework, you can use this in your EventMap:

<InlineInvoker method="{DB.initDB}" arguments="{['myDatabaseName.sqlite']}" />
<ObjectBuilder generator="{DBLoggingTarget}" >
   <Properties level="{LogEventLevel.ERROR}"/>
</ObjectBuilder>
<InlineInvoker method="{Log.addTarget}" arguments="{lastReturn}" />

After you run your app, you should see any generated log entries being recorded into your database.  This can help you later down the road, if you are supporting the application.