Package org.apache.log4j

Source Code of org.apache.log4j.AppenderSkeleton

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.log4j;

import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.OptionHandler;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.helpers.OnlyOnceErrorHandler;
import org.apache.log4j.helpers.LogLog;


/**
* Abstract superclass of the other appenders in the package.
*  This class provides the code for common functionality, such as
*  support for threshold filtering and support for general filters.
*
* @since 0.8.1
* @author Ceki Gülcü
* */
public abstract class AppenderSkeleton implements Appender, OptionHandler {

  /** The layout variable does not need to be set if the appender
      implementation has its own layout. */
  protected Layout layout;

  /** Appenders are named. */
  protected String name;

  /**
     There is no level threshold filtering by default.  */
  protected Priority threshold;

  /**
      It is assumed and enforced that errorHandler is never null.
  */
  protected ErrorHandler errorHandler = new OnlyOnceErrorHandler();

  /** The first filter in the filter chain. Set to <code>null</code>
      initially. */
  protected Filter headFilter;
  /** The last filter in the filter chain. */
  protected Filter tailFilter;

  /**
     Is this appender closed?
   */
  protected boolean closed = false;

    /**
     * Create new instance.
     */
    public AppenderSkeleton() {
        super();
    }

    /**
     * Create new instance.
     * Provided for compatibility with log4j 1.3.
     *
     * @param isActive true if appender is ready for use upon construction.
     *                 Not used in log4j 1.2.x.
     * @since 1.2.15
     */
    protected AppenderSkeleton(final boolean isActive) {
        super();
    }



  /**
     Derived appenders should override this method if option structure
     requires it.  */
  public
  void activateOptions() {
  }


  /**
     Add a filter to end of the filter list.

     @since 0.9.0
   */
  public
  void addFilter(Filter newFilter) {
    if(headFilter == null) {
      headFilter = tailFilter = newFilter;
    } else {
      tailFilter.setNext(newFilter);
      tailFilter = newFilter;   
    }
  }

  /**
     Subclasses of <code>AppenderSkeleton</code> should implement this
     method to perform actual logging. See also {@link #doAppend
     AppenderSkeleton.doAppend} method.

     @since 0.9.0
  */
  abstract
  protected
  void append(LoggingEvent event);


  /**
     Clear the filters chain.
    
     @since 0.9.0 */
  public
  void clearFilters() {
    headFilter = tailFilter = null;
  }

  /**
     Finalize this appender by calling the derived class'
     <code>close</code> method.

     @since 0.8.4 */
  public
  void finalize() {
    // An appender might be closed then garbage collected. There is no
    // point in closing twice.
    if(this.closed) {
        return;
    }

    LogLog.debug("Finalizing appender named ["+name+"].");
    close();
  }


  /**
      Return the currently set {@link ErrorHandler} for this
      Appender. 

      @since 0.9.0 */
  public
  ErrorHandler getErrorHandler() {
    return this.errorHandler;
  }


  /**
     Returns the head Filter.
    
     @since 1.1
  */
  public
  Filter getFilter() {
    return headFilter;
  }

  /**
      Return the first filter in the filter chain for this
      Appender. The return value may be <code>null</code> if no is
      filter is set.
     
  */
  public
  final
  Filter getFirstFilter() {
    return headFilter;
  }

  /**
     Returns the layout of this appender. The value may be null.
  */
  public
  Layout getLayout() {
    return layout;
  }


  /**
     Returns the name of this appender.
     @return name, may be null.
   */
  public
  final
  String getName() {
    return this.name;
  }

  /**
     Returns this appenders threshold level. See the {@link
     #setThreshold} method for the meaning of this option.
    
     @since 1.1 */
  public
  Priority getThreshold() {
    return threshold;
  }


  /**
     Check whether the message level is below the appender's
     threshold. If there is no threshold set, then the return value is
     always <code>true</code>.

  */
  public
  boolean isAsSevereAsThreshold(Priority priority) {
    return ((threshold == null) || priority.isGreaterOrEqual(threshold));
  }


  /**
    * This method performs threshold checks and invokes filters before
    * delegating actual logging to the subclasses specific {@link
    * AppenderSkeleton#append} method.
    * */
  public
  synchronized
  void doAppend(LoggingEvent event) {
    if(closed) {
      LogLog.error("Attempted to append to closed appender named ["+name+"].");
      return;
    }
   
    if(!isAsSevereAsThreshold(event.getLevel())) {
      return;
    }

    Filter f = this.headFilter;
   
    FILTER_LOOP:
    while(f != null) {
      switch(f.decide(event)) {
      case Filter.DENY: return;
      case Filter.ACCEPT: break FILTER_LOOP;
      case Filter.NEUTRAL: f = f.getNext();
      }
    }
   
    this.append(event);   
  }

  /**
      Set the {@link ErrorHandler} for this Appender.
      @since 0.9.0
  */
  public
  synchronized
  void setErrorHandler(ErrorHandler eh) {
    if(eh == null) {
      // We do not throw exception here since the cause is probably a
      // bad config file.
      LogLog.warn("You have tried to set a null error-handler.");
    } else {
      this.errorHandler = eh;
    }
  }

  /**
     Set the layout for this appender. Note that some appenders have
     their own (fixed) layouts or do not use one. For example, the
     {@link org.apache.log4j.net.SocketAppender} ignores the layout set
     here.
  */
  public
  void setLayout(Layout layout) {
    this.layout = layout;
  }

 
  /**
     Set the name of this Appender.
   */
  public
  void setName(String name) {
    this.name = name;
  }


  /**
     Set the threshold level. All log events with lower level
     than the threshold level are ignored by the appender.
    
     <p>In configuration files this option is specified by setting the
     value of the <b>Threshold</b> option to a level
     string, such as "DEBUG", "INFO" and so on.
    
     @since 0.8.3 */
  public
  void setThreshold(Priority threshold) {
    this.threshold = threshold;
 
}
TOP

Related Classes of org.apache.log4j.AppenderSkeleton

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.