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
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.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.
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'
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() ); }
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");
}
}
}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);
}
}
}
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.
LOGGER_FACTORY.setup = new SimpleTargetSetup( new TextFieldTarget );
To cancel all output again you can simply use a null setup.
LOGGER_FACTORY.setup = null;
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}""12:43:50.493 DEBUG - MyClass - Hello World"
(new TraceTarget).format = "{name} {time} {gmt} [{logLevel}] {message}"; // Results in statements like "mypackage.MyClass 12:43:50.493 GMT+0900 [DEBUG] Hello World"
To limit loggers to just enable certain levels you can use the
LevelTargetSetup.
This example just enables the error() and fatal() methods:
LOGGER_FACTORY.setup = new LevelTargetSetup( new TextFieldTarget, LogSetupLevel.ERROR );
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.
LOGGER_FACTORY.setup = new SimpleTargetSetup( mergeTargets( new TextFieldTarget, new TraceTarget ) );
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 );
LOGGER_FACTORY.setup = new RexExpSetup() .addTargetRule( /^org\.as3commons\./, ) .addTargetRule( /^com\.mycompany\./, new TextFieldTarget, LogSetupLevel.ERROR ) .addTargetRule( /^com\.mycompany\.hideThisPackage\./, null );
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)
);
}
}
}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;
}
}
}If you implement a target or even a whole setup process, let us know: We will be happy to feature it.