View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core;
15  
16  import java.util.List;
17  
18  import ch.qos.logback.core.filter.Filter;
19  import ch.qos.logback.core.spi.ContextAwareBase;
20  import ch.qos.logback.core.spi.FilterAttachableImpl;
21  import ch.qos.logback.core.spi.FilterReply;
22  import ch.qos.logback.core.status.WarnStatus;
23  
24  /**
25   * Sets a skeleton implementation for appenders.
26   * 
27   * <p> For more information about this appender, please refer to the online
28   * manual at http://logback.qos.ch/manual/appenders.html#AppenderBase
29   * 
30   * @author Ceki G&uuml;lc&uuml;
31   */
32  abstract public class AppenderBase<E> extends ContextAwareBase implements
33      Appender<E> {
34  
35    protected boolean started = false;
36  
37    /**
38     * The guard prevents an appender from repeatedly calling its own doAppend
39     * method.
40     */
41    private boolean guard = false;
42  
43    /**
44     * Appenders are named.
45     */
46    protected String name;
47  
48    private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
49  
50    public String getName() {
51      return name;
52    }
53  
54    private int statusRepeatCount = 0;
55    private int exceptionCount = 0;
56  
57    static final int ALLOWED_REPEATS = 5;
58  
59    public synchronized void doAppend(E eventObject) {
60      // WARNING: The guard check MUST be the first statement in the
61      // doAppend() method.
62  
63      // prevent re-entry.
64      if (guard) {
65        return;
66      }
67  
68      try {
69        guard = true;
70  
71        if (!this.started) {
72          if (statusRepeatCount++ < ALLOWED_REPEATS) {
73            addStatus(new WarnStatus(
74                "Attempted to append to non started appender [" + name + "].",
75                this));
76          }
77          return;
78        }
79  
80        if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
81          return;
82        }
83  
84        // ok, we now invoke derived class' implementation of append
85        this.append(eventObject);
86  
87      } catch (Exception e) {
88        if (exceptionCount++ < ALLOWED_REPEATS) {
89          addError("Appender [" + name + "] failed to append.", e);
90        }
91      } finally {
92        guard = false;
93      }
94    }
95  
96    abstract protected void append(E eventObject);
97  
98    /**
99     * Set the name of this appender.
100    */
101   public void setName(String name) {
102     this.name = name;
103   }
104 
105   public void start() {
106     started = true;
107   }
108 
109   public void stop() {
110     started = false;
111   }
112 
113   public boolean isStarted() {
114     return started;
115   }
116 
117   public String toString() {
118     return this.getClass().getName() + "[" + name + "]";
119   }
120 
121   public void addFilter(Filter<E> newFilter) {
122     fai.addFilter(newFilter);
123   }
124 
125   public void clearAllFilters() {
126     fai.clearAllFilters();
127   }
128 
129   public List<Filter<E>> getCopyOfAttachedFiltersList() {
130     return fai.getCopyOfAttachedFiltersList();
131   }
132 
133   public FilterReply getFilterChainDecision(E event) {
134     return fai.getFilterChainDecision(event);
135   }
136 
137 }