View Javadoc

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