1
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
31 abstract public class UnsynchronizedAppenderBase<E> extends ContextAwareBase implements Appender<E> {
32
33 protected boolean started = false;
34
35
36
37
38
42 private ThreadLocal<Boolean> guard = new ThreadLocal<Boolean>();
43
44
47 protected String name;
48
49 private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
50
51 public String getName() {
52 return name;
53 }
54
55 private int statusRepeatCount = 0;
56 private int exceptionCount = 0;
57
58 static final int ALLOWED_REPEATS = 3;
59
60 public void doAppend(E eventObject) {
61
62
63
64
65 if (Boolean.TRUE.equals(guard.get())) {
66 return;
67 }
68
69 try {
70 guard.set(Boolean.TRUE);
71
72 if (!this.started) {
73 if (statusRepeatCount++ < ALLOWED_REPEATS) {
74 addStatus(new WarnStatus("Attempted to append to non started appender [" + name + "].", this));
75 }
76 return;
77 }
78
79 if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
80 return;
81 }
82
83
84 this.append(eventObject);
85
86 } catch (Exception e) {
87 if (exceptionCount++ < ALLOWED_REPEATS) {
88 addError("Appender [" + name + "] failed to append.", e);
89 }
90 } finally {
91 guard.set(Boolean.FALSE);
92 }
93 }
94
95 abstract protected void append(E eventObject);
96
97
100 public void setName(String name) {
101 this.name = name;
102 }
103
104 public void start() {
105 started = true;
106 }
107
108 public void stop() {
109 started = false;
110 }
111
112 public boolean isStarted() {
113 return started;
114 }
115
116 public String toString() {
117 return this.getClass().getName() + "[" + name + "]";
118 }
119
120 public void addFilter(Filter<E> newFilter) {
121 fai.addFilter(newFilter);
122 }
123
124 public void clearAllFilters() {
125 fai.clearAllFilters();
126 }
127
128 public List<Filter<E>> getCopyOfAttachedFiltersList() {
129 return fai.getCopyOfAttachedFiltersList();
130 }
131
132 public FilterReply getFilterChainDecision(E event) {
133 return fai.getFilterChainDecision(event);
134 }
135 }
136