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> 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 Appender<E> {
33  
34      protected volatile boolean started = false;
35  
36      /**
37       * The guard prevents an appender from repeatedly calling its own doAppend
38       * method.
39       */
40      private boolean guard = false;
41  
42      /**
43       * Appenders are named.
44       */
45      protected String name;
46  
47      private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
48  
49      public String getName() {
50          return name;
51      }
52  
53      private int statusRepeatCount = 0;
54      private int exceptionCount = 0;
55  
56      static final int ALLOWED_REPEATS = 5;
57  
58      public synchronized void doAppend(E eventObject) {
59          // WARNING: The guard check MUST be the first statement in the
60          // doAppend() method.
61  
62          // prevent re-entry.
63          if (guard) {
64              return;
65          }
66  
67          try {
68              guard = true;
69  
70              if (!this.started) {
71                  if (statusRepeatCount++ < ALLOWED_REPEATS) {
72                      addStatus(new WarnStatus("Attempted to append to non started appender [" + name + "].", this));
73                  }
74                  return;
75              }
76  
77              if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
78                  return;
79              }
80  
81              // ok, we now invoke derived class' implementation of append
82              this.append(eventObject);
83  
84          } catch (Exception e) {
85              if (exceptionCount++ < ALLOWED_REPEATS) {
86                  addError("Appender [" + name + "] failed to append.", e);
87              }
88          } finally {
89              guard = false;
90          }
91      }
92  
93      abstract protected void append(E eventObject);
94  
95      /**
96       * Set the name of this appender.
97       */
98      public void setName(String name) {
99          this.name = name;
100     }
101 
102     public void start() {
103         started = true;
104     }
105 
106     public void stop() {
107         started = false;
108     }
109 
110     public boolean isStarted() {
111         return started;
112     }
113 
114     public String toString() {
115         return this.getClass().getName() + "[" + name + "]";
116     }
117 
118     public void addFilter(Filter<E> newFilter) {
119         fai.addFilter(newFilter);
120     }
121 
122     public void clearAllFilters() {
123         fai.clearAllFilters();
124     }
125 
126     public List<Filter<E>> getCopyOfAttachedFiltersList() {
127         return fai.getCopyOfAttachedFiltersList();
128     }
129 
130     public FilterReply getFilterChainDecision(E event) {
131         return fai.getFilterChainDecision(event);
132     }
133 
134 }