1 /* 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.mozilla.org/MPL/MPL-1.1.html 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.as2lib.env.event.distributor.EventDistributorControl; 18 import org.as2lib.env.event.distributor.SimpleEventDistributorControl; 19 import org.as2lib.env.log.LogHandler; 20 import org.as2lib.env.log.ConfigurableLogger; 21 import org.as2lib.env.log.LogLevel; 22 import org.as2lib.env.log.LogMessage; 23 import org.as2lib.env.log.logger.AbstractLogger; 24 25 /** 26 * {@code SimpleLogger} is a simple implementation of the {@code ConfigurableLogger} 27 * interface. 28 * 29 * <p>The basic methods to write the log messages are {@link #log}, {@link #debug}, 30 * {@link #info}, {@link #warning} and {@link #fatal}. 31 * 32 * <p>The first thing to note is that you can log messages at different levels. 33 * These levels are {@code DEBUG}, {@code INFO}, {@code WARNING}, {@code ERROR} 34 * and {@code FATAL}. Depending on what level has been set only messages at a 35 * given level are logged. The levels are organized in a hierarchical manner. That 36 * means if you set the log level to {@code ALL} every messages is logged. If you 37 * set it to {@code ERROR} only messages at {@code ERROR} and {@code FATAL} level 38 * are logged and so on. It is also possible to define your own set of levels. You 39 * can therefor use the {@link #isEnabled} and {@link #log} methods. 40 * 41 * <p>To do not waste unnecessary performance in constructing log messages that are 42 * not logged you can use the methods {@link #isEnabled}, {@link #isDebugEnabled}, 43 * {@link #isInfoEnabled}, {@link #isWarningEnabled}, {@link #isErrorEnabled} 44 * and {@link #isFatalEnabled}. 45 * 46 * <p>Note that the message does in neither case have to be a string. That means 47 * you can pass-in messages and let the actual log handler decide how to produce a 48 * string representation of the message. This is in most cases done by using the 49 * {@code toString} method of the specific message. You can use this method to do 50 * not lose performance in cases where the message is not logged. 51 * 52 * <p>The actaul log output is made by log handlers. To configure and 53 * access the handlers of this logger you can use the methods {@link #addHandler}, 54 * {@link #removeHandler}, {@link #removeAllHandlers} and {@link #getAllHandlers}. 55 * There are a few pre-defined handlers for different output devices. 56 * Take a look at the {@code org.as2lib.env.log.handler} package for these. 57 * 58 * <p>Example: 59 * <code> 60 * var logger:SimpleLogger = new SimpleLogger("mySimpleLogger"); 61 * // adds a trace handler that is responsible for making the output 62 * logger.addHandler(new TraceHandler()); 63 * // checks if the output gets actually made 64 * if (logger.isInfoEnabled()) { 65 * // log the message at the info level 66 * logger.info("This is an informative log message."); 67 * } 68 * </code> 69 * 70 * <p>This logger cannot be used with the {@code LoggerHierarchy} because it does 71 * not offer hierarchy support. If you want to use your logger in a hierarchy use 72 * the {@link SimpleHierarchicalLogger} instead. 73 * 74 * @author Simon Wacker 75 * @see org.as2lib.env.log.repository.LoggerHierarchy 76 */ 77 class org.as2lib.env.log.logger.SimpleLogger extends AbstractLogger implements ConfigurableLogger { 78 79 /** Makes the static variables of the super-class accessible through this class. */ 80 private static var __proto__:Function = AbstractLogger; 81 82 /** The set level. */ 83 private var level:LogLevel; 84 85 /** The set level as number. */ 86 private var levelAsNumber:Number; 87 88 /** Distributor control that controls the distributor. */ 89 private var distributorControl:EventDistributorControl; 90 91 /** Typed distributor that distributes messages to all log handlers. */ 92 private var distributor:LogHandler; 93 94 /** The name of this logger. */ 95 private var name:String; 96 97 /** 98 * Constructs a new {@code SimpleLogger} instance. 99 * 100 * <p>The default log level is {@code ALL}. This means all messages regardless of 101 * their level are logged. 102 * 103 * <p>The logger {@code name} is by default shown in the log message to identify 104 * where the message came from. 105 * 106 * @param name (optional) the name of this logger 107 */ 108 public function SimpleLogger(name:String) { 109 this.name = name; 110 distributorControl = new SimpleEventDistributorControl(LogHandler, false); 111 distributor = this.distributorControl.getDistributor(); 112 level = ALL; 113 levelAsNumber = level.toNumber(); 114 } 115 116 /** 117 * Returns the name of this logger. 118 * 119 * <p>This method returns {@code null} if no name has been set via the 120 * {@link #setName} method nor on construction. 121 * 122 * @return the name of this logger 123 */ 124 public function getName(Void):String { 125 return name; 126 } 127 128 /** 129 * Sets the name of this logger. 130 * 131 * <p>The name is by default shown in the log message. 132 * 133 * @param name the new name of this logger 134 */ 135 public function setName(name:String):Void { 136 this.name = name; 137 } 138 139 /** 140 * Sets the log level. 141 * 142 * <p>The log level determines which messages are logged and which are not. 143 * 144 * <p>A level of value {@code null} or {@code undefined} is interpreted as level 145 * {@code ALL} which is also the default level. 146 * 147 * @param level the new log level 148 */ 149 public function setLevel(level:LogLevel):Void { 150 if (level) { 151 this.level = level; 152 levelAsNumber = level.toNumber(); 153 } else { 154 this.level = ALL; 155 levelAsNumber = level.toNumber(); 156 } 157 } 158 159 /** 160 * Returns the set level. 161 * 162 * @return the set level 163 */ 164 public function getLevel(Void):LogLevel { 165 return level; 166 } 167 168 /** 169 * Adds a new log handler. 170 * 171 * <p>Log handlers are used to actually log the messages. They determine what 172 * information to log and to which output device. 173 * 174 * <p>This method simply does nothing if the passed-in handler is {@code null} or 175 * {@code undefined}. 176 * 177 * @param handler the new log handler to log messages 178 */ 179 public function addHandler(handler:LogHandler):Void { 180 if (handler) { 181 distributorControl.addListener(handler); 182 } 183 } 184 185 /** 186 * Removes all occerrences of the passed-in log {@code handler}. 187 * 188 * <p>If the passed-in {@code handler} is {@code null} or {@code undefined} the 189 * method invocation is simply ignored. 190 * 191 * @param handler the log handler to remove 192 */ 193 public function removeHandler(handler:LogHandler):Void { 194 if (handler) { 195 distributorControl.removeListener(handler); 196 } 197 } 198 199 /** 200 * Removes all added log handlers. 201 */ 202 public function removeAllHandlers(Void):Void { 203 distributorControl.removeAllListeners(); 204 } 205 206 /** 207 * Returns all handlers that were added to this logger. 208 * 209 * <p>If there are no added handlers an empty array is returned. 210 * 211 * @return all added log handlers 212 */ 213 public function getAllHandlers(Void):Array { 214 return distributorControl.getAllListeners(); 215 } 216 217 /** 218 * Checks whether this logger is enabled for the passed-in {@code level}. 219 * 220 * <p>{@code false} will be returned if: 221 * <ul> 222 * <li>This logger is not enabled for the passed-in {@code level}.</li> 223 * <li>The passed-in {@code level} is {@code null} or {@code undefined}.</li> 224 * </ul> 225 * 226 * <p>Using this method as shown in the class documentation may improve performance 227 * depending on how long the log message construction takes. 228 * 229 * @param level the level to make the check upon 230 * @return {@code true} if this logger is enabled for the given {@code level} else 231 * {@code false} 232 * @see #log 233 */ 234 public function isEnabled(level:LogLevel):Boolean { 235 if (!level) return false; 236 return (levelAsNumber >= level.toNumber()); 237 } 238 239 /** 240 * Checks if this logger is enabled for debug level log messages. 241 * 242 * <p>Using this method as shown in the class documentation may improve performance 243 * depending on how long the log message construction takes. 244 * 245 * @return {@code true} if debug messages are logged 246 * @see org.as2lib.env.log.level.AbstractLogLevel#DEBUG 247 * @see #debug 248 */ 249 public function isDebugEnabled(Void):Boolean { 250 return (levelAsNumber >= debugLevelAsNumber); 251 } 252 253 /** 254 * Checks if this logger is enabled for info level log messages. 255 * 256 * <p>Using this method as shown in the class documentation may improve performance 257 * depending on how long the log message construction takes. 258 * 259 * @return {@code true} if info messages are logged 260 * @see org.as2lib.env.log.level.AbstractLogLevel#INFO 261 * @see #info 262 */ 263 public function isInfoEnabled(Void):Boolean { 264 return (levelAsNumber >= infoLevelAsNumber); 265 } 266 267 /** 268 * Checks if this logger is enabled for warning level log messages. 269 * 270 * <p>Using this method as shown in the class documentation may improve performance 271 * depending on how long the log message construction takes. 272 * 273 * @return {@code true} if warning messages are logged 274 * @see org.as2lib.env.log.level.AbstractLogLevel#WARNING 275 * @see #warning 276 */ 277 public function isWarningEnabled(Void):Boolean { 278 return (levelAsNumber >= warningLevelAsNumber); 279 } 280 281 /** 282 * Checks if this logger is enabled for error level log messages. 283 * 284 * <p>Using this method as shown in the class documentation may improve performance 285 * depending on how long the log message construction takes. 286 * 287 * @return {@code true} if error messages are logged 288 * @see org.as2lib.env.log.level.AbstractLogLevel#ERROR 289 * @see #error 290 */ 291 public function isErrorEnabled(Void):Boolean { 292 return (levelAsNumber >= errorLevelAsNumber); 293 } 294 295 /** 296 * Checks if this logger is enabled for fatal level log messages. 297 * 298 * <p>Using this method as shown in the class documentation may improve performance 299 * depending on how long the log message construction takes. 300 * 301 * @return {@code true} if fatal messages are logged 302 * @see org.as2lib.env.log.level.AbstractLogLevel#FATAL 303 * @see #fatal 304 */ 305 public function isFatalEnabled(Void):Boolean { 306 return (levelAsNumber >= fatalLevelAsNumber); 307 } 308 309 /** 310 * Logs the {@code message} at the given {@code level}. 311 * 312 * <p>The {@code message} is only logged when this logger is enabled for the 313 * passed-in {@code level}. 314 * 315 * @param message the message object to log 316 * @param level the specific level at which the {@code message} shall be logged 317 * @see #isEnabled 318 */ 319 public function log(message, level:LogLevel):Void { 320 if (isEnabled(level)) { 321 distributor.write(new LogMessage(message, level, name)); 322 } 323 } 324 325 /** 326 * Logs the {@code message} object at debug level. 327 * 328 * <p>The {@code message} is only logged when the level is set to {@code DEBUG} or 329 * a level above. 330 * 331 * @param message the message object to log 332 * @see #isDebugEnabled 333 */ 334 public function debug(message):Void { 335 if (isDebugEnabled()) { 336 distributor.write(new LogMessage(message, debugLevel, name)); 337 } 338 } 339 340 /** 341 * Logs the {@code message} object at info level. 342 * 343 * <p>The {@code message} gets only logged when the level is set to {@code INFO} 344 * or a level above. 345 * 346 * @param message the message object to log 347 * @see #isInfoEnabled 348 */ 349 public function info(message):Void { 350 if (isInfoEnabled()) { 351 distributor.write(new LogMessage(message, infoLevel, name)); 352 } 353 } 354 355 /** 356 * Logs the {@code message} object at warning level. 357 * 358 * <p>The {@code message} gets only logged when the level is set to {@code WARNING} 359 * or a level above. 360 * 361 * @param message the message object to log 362 * @see #isWarningEnabled 363 */ 364 public function warning(message):Void { 365 if (isWarningEnabled()) { 366 distributor.write(new LogMessage(message, warningLevel, name)); 367 } 368 } 369 370 /** 371 * Logs the {@code message} object at error level. 372 * 373 * <p>The {@code message} gets only logged when the level is set to {@code ERROR} 374 * or a level above. 375 * 376 * @param message the message object to log 377 * @see #isErrorEnabled 378 */ 379 public function error(message):Void { 380 if (isErrorEnabled()) { 381 distributor.write(new LogMessage(message, errorLevel, name)); 382 } 383 } 384 385 /** 386 * Logs the {@code message} object at fatal level. 387 * 388 * <p>The {@code message} gets only logged when the level is set to {@code FATAL} 389 * or a level above. 390 * 391 * @param message the message object to log 392 * @see #isFatalEnabled 393 */ 394 public function fatal(message):Void { 395 if (isFatalEnabled()) { 396 distributor.write(new LogMessage(message, fatalLevel, name)); 397 } 398 } 399 400 }