View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, 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>
28   * For more information about this appender, please refer to the online manual
29   * at http://logback.qos.ch/manual/appenders.html#AppenderBase
30   * 
31   * @author Ceki G&uuml;lc&uuml;
32   */
33  abstract public class AppenderBase<E> extends ContextAwareBase implements Appender<E> {
34  
35      protected volatile 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("Attempted to append to non started appender [" + name + "].", this));
74                  }
75                  return;
76              }
77  
78              if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
79                  return;
80              }
81  
82              // ok, we now invoke derived class' implementation of append
83              this.append(eventObject);
84  
85          } catch (Exception e) {
86              if (exceptionCount++ < ALLOWED_REPEATS) {
87                  addError("Appender [" + name + "] failed to append.", e);
88              }
89          } finally {
90              guard = false;
91          }
92      }
93  
94      abstract protected void append(E eventObject);
95  
96      /**
97       * Set the name of this appender.
98       */
99      public void setName(String name) {
100         this.name = name;
101     }
102 
103     public void start() {
104         started = true;
105     }
106 
107     public void stop() {
108         started = false;
109     }
110 
111     public boolean isStarted() {
112         return started;
113     }
114 
115     public String toString() {
116         return this.getClass().getName() + "[" + name + "]";
117     }
118 
119     public void addFilter(Filter<E> newFilter) {
120         fai.addFilter(newFilter);
121     }
122 
123     public void clearAllFilters() {
124         fai.clearAllFilters();
125     }
126 
127     public List<Filter<E>> getCopyOfAttachedFiltersList() {
128         return fai.getCopyOfAttachedFiltersList();
129     }
130 
131     public FilterReply getFilterChainDecision(E event) {
132         return fai.getFilterChainDecision(event);
133     }
134 
135 }