pupsnow / as3-commons

Automatically exported from code.google.com/p/as3-commons
1 stars 0 forks source link

Merging LevelTargetSetups - setups override each other #91

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

LOGGER_FACTORY.setup = new MergedSetup(
new LevelTargetSetup(new TraceTarget(), LogSetupLevel.ALL),
new LevelTargetSetup(new AirFileTarget(), LogSetupLevel.ERROR));

What is the expected output? What do you see instead?

I would like to set up several targets with different sets of levels, as in 
preceding example I want to trace all levels and log to file only errors and 
fatal. The current implementation of Logger allows to have only one target for 
particular log level. That's why on trace console I see all levels except error 
and fatal (which is wrong), and in file I get errors and fatal (which is 
correct). 

In out application the use case is very simple - we want to have one log file 
with all logs and one that has only errors. We cannot do this with current 
implementation.

This is what I think should be done to fix it: In logger instead of simple 
variables like

public var infoTarget:ILogTarget;

you could have:

private var _infoTargets: Array = [];

public function set infoTarget(value: ILogTarget): void {
   if (value) {
      _infoTargets.push(value);
   } else {
      _infoTargets = [];
   }
}

and when logging just check the targets array:

public function info(message: *, parameters: Array = null): void {
      for each (var target: ILogTarget in _infoTargets) {
        target.log(_name, _shortName, 0x0010 /*INFO*/,
          _startTime + getTimer(), message, parameters, _person);
    }
}

public function get infoEnabled(): Boolean {
      return _infoTargets.length != 0;
}

This is the simplest solution. The real problem is that I can't use my own 
logger class, because LoggerFactory hardcodes the implementation of ILogger.
I could make my own LoggerFactory but.. the Logger class is final so I can't 
extend it and the ILogSetup.applyTo(logger:Logger) uses Logger instead of 
ILogger.

I think you should consider enabling the core classes to be more open and 
configurable. Just create ILoggerFactory and enable setting own implementation 
and change ILogSetup (and other places) to use ILogger.

LOGGER_FACTORY = new MyLoggerFactory(MyLogger);
LOGGER_FACTORY.setup = new MergedSetup(
new LevelTargetSetup(new TraceTarget(), LogSetupLevel.ALL),
new LevelTargetSetup(new AirFileTarget(), LogSetupLevel.ERROR));

I Hope this makes sense;)

What version of the product are you using? On what operating system?

2.6

Please provide any additional information below.

BTW, great job with the whole as3-commons libs!

Original issue reported on code.google.com by matys8...@gmail.com on 21 Sep 2011 at 10:08

GoogleCodeExporter commented 9 years ago
I think you misunderstood the setup process. (Which means we have to work on 
the documentation). Maybe its easy to explain if I show what you want like this:

  * debug -> trace
  * info -> trace
  * warn -> trace
  * error -> trace,air
  * fatal -> trace,air

Each of the level should be redirected to a target. You recognized that we just 
have 1 logTarget per level. It is possible to mergeTargets (a class in our 
list) which combines multiple targets to one.

   var mergedTarget: MergedTarget = mergeTargets(trace,air);

Now: Lets say I apply just "trace" to all levels:

   LOGGER_FACTORY.setup = new SimpleTargetSetup(trace);

then all our levels look like this:

  * debug -> trace
  * info -> trace
  * warn -> trace
  * error -> trace
  * fatal -> trace

As you said correctly before: MergedSetup is executed after the first one. 
Luckily: LevelTargetSetup overrides only the active levels, so:

   var trace: TraceTarget = new TraceTarget;
   var air: AirFileTarget = new AirFileTarget;
   LOGGER_FACTORY.setup = mergeSetups(
      new SimpleTargetSetup(trace),
      new LevelTargetSetup(mergeTargets(trace,air), LogSetupLevel.ERROR);
   );

Now, the second setup will override the ERROR and FATAL target to the merged 
target.

  * debug -> trace
  * info -> trace
  * warn -> trace
  * error -> merged(trace,air)
  * fatal -> merged(trace,air)

I hope this makes the setup process a little clearer. We plan to have a "log4j" 
style setup in the next release which works in the semantics like log4j, like 
in your example.

Original comment by martin.h...@gmail.com on 22 Sep 2011 at 2:32

GoogleCodeExporter commented 9 years ago
Thank you so much!

Original comment by matys8...@gmail.com on 22 Sep 2011 at 7:26