Usage

The use of as3commons-logging is simple and straightforward, when in need of a logger use the getLogger() function to get one

import org.as3commons.logging.api.getLogger;

getLogger("myLogger").info("Some logging message");

The loggers do not need to follow any pattern but they can follow one passing a class to the logger

getLogger(MyClass).info("Some logging message");
Now the loggers always show the passed-in class name. This leads to a very common and reasonable pattern of having one logger per class.

A common class could look straightforward like this:
package {
    import org.as3commons.logging.api.ILogger;
    import org.as3commons.logging.api.getLogger;

    class MyClass {
        private static const logger: ILogger = getLogger( MyClass );

        public function foo() {
            logger.info("Some logging message");
        }
    }
}

Since we disabled (since v2.5) logging by default, as any reasonable logging framework does, you need to enable it first to see something.

package {
    import flash.display.Sprite;
    import org.as3commons.logging.api.LOGGER_FACTORY;
    
    class MyClass extends Sprite {
        public function MyClass() {
            LOGGER_FACTORY.setup = new SimpleTargetSetup( new TraceTarget );
        }
    }	
}

The loggers have 5 methods to log output to, each referring to the relevance of the statement.

logger.debug("..."); // To help in the debugging process of your code.
logger.info("...");  // Let the users of your code know what is going on.
logger.warn("...");  // Warn if some code doesn't run efficiently or could run better.
logger.error("..."); // Warn that a error occurred that your code could deal with.
logger.fatal("..."); // Scream for help if a error occurs that you could not deal with but somehow found out about.
By using them wisely you can improve the quality of your output.

Any message sent may use parameters to inform about objects/content related to the code:

logger.info("parameter {0} refers to {1}", ["P0", "P1"]);
// output 'parameter P0 refers to P1'
This may be particularly useful if you use a good log output that also allows to look deeper into the parameters. If you have simple outputs it will just stringify the statement.

When you are working more with logging in your application you might over time even develop more complex log statements which require some processing. In case you run into statements that do more than just passing parameters then it might be reasonable to check if the certain method is enabled or not.

if( logger.infoEnabled ) {
    logger.info( complexLogStatement() );
}
This way the complexLogStatement() is just called when really needed.

For a team of users one might want to have loggers per user that sends out the log statement. Since various loggers allow to show them as3commons-logging also offers support to use that.

package {
    import org.as3commons.logging.api.ILogger;
    import org.as3commons.logging.api.getLogger;
    
    
    class MyClass {
        public static const mLog: ILogger = getLogger( MyClass, "Martin Heidegger");
        public static const cLog: ILogger = getLogger( MyClass, "Christophe Herreman");

        public function foo() {
            mLog.info("Some logging message by Martin");
            cLog.info("Some logging message by Christophe");
        }
    }
}
With this it is also possible to later on filter to the statements of users.

Since Flash Player 10.2 it is possible to listen to the global error event dispatcher. With version 2.1 as3commons-logging introduced a util to capture that errors and redirect it as fatal log statements.

package {
    import flash.display.Sprite;
    import org.as3commons.logging.util.captureUncaughtErrors;
    
    public class MyApplication extends Sprite {
        public function MyApplication() {
            captureUncaughtErrors(loaderInfo);
        }
    } 
}

Setup

By default all the log statements will be hidden.

To change that you need to change the setup of LOGGER_FACTORY which (in fact) manages all the loggers retrieved via getLogger().
You can change the setup of the loggers whenever you like, even though its recommended to do it at the startup of your application.

For just changing the target of all loggers the SimpleTargetSetup can be used.

That would redirect all log statements to the TextFieldTarget.
A list of all targets that are available by default can be found in the API docs for the org.as3commons.logging.setup.target package

To cancel all output again you can simply use a null setup.

More complex setups are separated in the concepts of ILogSetup and ILogTarget. A ILogSetup defines which ILogTargets are given to the levels of each ILogger returned by the system.

As mentioned before the default target to render statements is the TraceTarget.

The TraceTarget will render the statements, by default in the format of

    "{time} {logLevel} - {shortName} - {message}"
resulting in statements like
    "12:43:50.493 DEBUG - MyClass - Hello World"
This can be easily changed by using the format property.
(new TraceTarget).format = "{name} {time} {gmt} [{logLevel}] {message}";
// Results in statements like "mypackage.MyClass 12:43:50.493 GMT+0900 [DEBUG] Hello World"
All implementations of IFormattingLogTarget can be changed the same way. A list of all formatting available can be found in the API.

To limit loggers to just enable certain levels you can use the LevelTargetSetup.
This example just enables the error() and fatal() methods:

If you want to have many targets rendering the same statements you can use mergeTargets(). It will merge two or more targets into one new target.

To just render some loggers and exclude others the RegExpSetup offers a simple, straight forward way.
By adding a statement with addTargetRule() its possible to define targets to certain loggers:

LOGGER_FACTORY.setup = new RexExpSetup().addTargetRule( /^org\.as3commons\./, new TraceTarget );
This might for example just trace() the output of all loggers that start with "org.as3commons.".

Any further added statement will be added to the checklist:
LOGGER_FACTORY.setup = new RexExpSetup()
                              .addTargetRule( /^org\.as3commons\./,  )
                              .addTargetRule( /^com\.mycompany\./, new TextFieldTarget, LogSetupLevel.ERROR )
                              .addTargetRule( /^com\.mycompany\.hideThisPackage\./, null );

Custom targets and Loggers

To have your own, custom, targets all you have to do is implementing ILogTarget.

Fortunately that is pretty fast done by just implementing one method. Here is what a very, very simple target could look like:

package {
    import org.as3commons.logging.api.ILogTarget;
    import org.as3commons.logging.util.LogMessageFormatter;
    
    public final class VerySimpleTraceTarget implements ILogTarget {
        
        private const _formatter: LogMessageFormatter
            = new LogMessageFormatter("{logTime} {logLevel} {name} {message}");
        
        public function log(name:String, shortName:String, level:int, timeStamp:Number,
                            message:*, parameters:Array, person:String):void {
            trace( _formatter.format(
                                  name, shortName, level, timeStamp,
                                  message, parameters, person)
            );
        }
    }
}
Note that the level passed in to the target is of type int and not of the type "LogSetupLevel".

Any target may be used in the setup process as outlined earlier.

Developing a custom ILogSetup is not much more diffcult. All your custom setup has to do is to manipulate the given Logger (!not ILogger) by filling the desired ILogTargets to each desired port.

A setup that just fills the error ports could look like this:

package {
    import org.as3commons.logging.api.ILogTarget;
    import org.as3commons.logging.Logger;
    
    public final class JustErrorSetup implements ILogSetup {
        
        private var _target: ILogTarget;
        
        public function JustErrorSetup( target:ILogTarget ) {
            _target = target;
        }
        
        function applyTo(logger:Logger):void {
            logger.errorTarget = _target;
        }
    }
}
And ... Done!

If you implement a target or even a whole setup process, let us know: We will be happy to feature it.