1
2
3
4
5
6
7
8
9
10
11 package ch.qos.logback.classic;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.Hashtable;
18 import java.util.List;
19
20 import org.slf4j.ILoggerFactory;
21 import org.slf4j.Marker;
22
23 import ch.qos.logback.classic.spi.LoggerComparator;
24 import ch.qos.logback.classic.spi.LoggerContextListener;
25 import ch.qos.logback.classic.spi.LoggerContextRemoteView;
26 import ch.qos.logback.classic.spi.TurboFilterList;
27 import ch.qos.logback.classic.turbo.TurboFilter;
28 import ch.qos.logback.core.ContextBase;
29 import ch.qos.logback.core.CoreConstants;
30 import ch.qos.logback.core.spi.FilterReply;
31 import ch.qos.logback.core.spi.LifeCycle;
32 import ch.qos.logback.core.status.StatusListener;
33 import ch.qos.logback.core.status.StatusManager;
34 import ch.qos.logback.core.status.WarnStatus;
35
36
37
38
39
40
41
42
43
44
45 public class LoggerContext extends ContextBase implements ILoggerFactory,
46 LifeCycle {
47
48 public static final String ROOT_NAME = "root";
49
50 final Logger root;
51 private int size;
52 private int noAppenderWarning = 0;
53 final private List<LoggerContextListener> loggerContextListenerList = new ArrayList<LoggerContextListener>();
54
55
56
57
58
59 private Hashtable<String, Logger> loggerCache;
60
61 private LoggerContextRemoteView loggerContextRemoteView;
62 private final TurboFilterList turboFilterList = new TurboFilterList();
63
64 boolean started = false;
65
66 public LoggerContext() {
67 super();
68 this.loggerCache = new Hashtable<String, Logger>();
69 this.loggerContextRemoteView = new LoggerContextRemoteView(this);
70 this.root = new Logger(ROOT_NAME, null, this);
71 this.root.setLevel(Level.DEBUG);
72 loggerCache.put(ROOT_NAME, root);
73 putObject(CoreConstants.EVALUATOR_MAP, new HashMap());
74 size = 1;
75 }
76
77
78
79
80
81 private void syncRemoteView() {
82 loggerContextRemoteView = new LoggerContextRemoteView(this);
83 for (Logger logger : loggerCache.values()) {
84 logger.buildRemoteView();
85 }
86 }
87
88 @Override
89 public void putProperty(String key, String val) {
90 super.putProperty(key, val);
91 syncRemoteView();
92 }
93
94 @Override
95 public void setName(String name) {
96 super.setName(name);
97 syncRemoteView();
98 }
99
100 public final Logger getLogger(final Class clazz) {
101 return getLogger(clazz.getName());
102 }
103
104 public final Logger getLogger(final String name) {
105
106 if (name == null) {
107 throw new IllegalArgumentException("name argument cannot be null");
108 }
109
110
111
112 if (ROOT_NAME.equalsIgnoreCase(name)) {
113 return root;
114 }
115
116 int i = 0;
117 Logger logger = root;
118
119
120
121 Logger childLogger = (Logger) loggerCache.get(name);
122
123 if (childLogger != null) {
124 return childLogger;
125 }
126
127
128
129 String childName;
130 while (true) {
131 int h = name.indexOf(ClassicGlobal.LOGGER_SEPARATOR, i);
132 if (h == -1) {
133 childName = name;
134 } else {
135 childName = name.substring(0, h);
136 }
137
138 i = h + 1;
139 synchronized (logger) {
140 childLogger = logger.getChildByName(childName);
141 if (childLogger == null) {
142 childLogger = logger.createChildByName(childName);
143 loggerCache.put(childName, childLogger);
144 incSize();
145 }
146 }
147 logger = childLogger;
148 if (h == -1) {
149 return childLogger;
150 }
151 }
152 }
153
154 private void incSize() {
155 size++;
156 }
157
158 int size() {
159 return size;
160 }
161
162
163
164
165
166
167
168
169 public Logger exists(String name) {
170 return (Logger) loggerCache.get(name);
171 }
172
173 final void noAppenderDefinedWarning(final Logger logger) {
174 if (noAppenderWarning++ == 0) {
175 getStatusManager().add(
176 new WarnStatus("No appenders present in context [" + getName()
177 + "] for logger [" + logger.getName() + "].", logger));
178 }
179 }
180
181 public List<Logger> getLoggerList() {
182 Collection<Logger> collection = loggerCache.values();
183 List<Logger> loggerList = new ArrayList<Logger>(collection);
184 Collections.sort(loggerList, new LoggerComparator());
185 return loggerList;
186 }
187
188 public LoggerContextRemoteView getLoggerContextRemoteView() {
189 return loggerContextRemoteView;
190 }
191
192
193
194
195 public void reset() {
196 root.recursiveReset();
197 resetTurboFilterList();
198 fireOnReset();
199 resetListenersExceptResetResistant();
200 resetStatusListeners();
201 }
202
203 private void resetStatusListeners() {
204 StatusManager sm = getStatusManager();
205 for (StatusListener sl : sm.getCopyOfStatusListenerList()) {
206 sm.remove(sl);
207 }
208 }
209
210 public TurboFilterList getTurboFilterList() {
211 return turboFilterList;
212 }
213
214 public void addTurboFilter(TurboFilter newFilter) {
215 turboFilterList.add(newFilter);
216 }
217
218
219
220
221
222 public void resetTurboFilterList() {
223 for (TurboFilter tf : turboFilterList) {
224 tf.stop();
225 }
226 turboFilterList.clear();
227 }
228
229 final FilterReply getTurboFilterChainDecision_0_3OrMore(final Marker marker,
230 final Logger logger, final Level level, final String format,
231 final Object[] params, final Throwable t) {
232 if (turboFilterList.size() == 0) {
233 return FilterReply.NEUTRAL;
234 }
235 return turboFilterList.getTurboFilterChainDecision(marker, logger, level,
236 format, params, t);
237 }
238
239 final FilterReply getTurboFilterChainDecision_1(final Marker marker,
240 final Logger logger, final Level level, final String format,
241 final Object param, final Throwable t) {
242 if (turboFilterList.size() == 0) {
243 return FilterReply.NEUTRAL;
244 }
245 return turboFilterList.getTurboFilterChainDecision(marker, logger, level,
246 format, new Object[] { param }, t);
247 }
248
249 final FilterReply getTurboFilterChainDecision_2(final Marker marker,
250 final Logger logger, final Level level, final String format,
251 final Object param1, final Object param2, final Throwable t) {
252 if (turboFilterList.size() == 0) {
253 return FilterReply.NEUTRAL;
254 }
255 return turboFilterList.getTurboFilterChainDecision(marker, logger, level,
256 format, new Object[] { param1, param2 }, t);
257 }
258
259
260 public void addListener(LoggerContextListener listener) {
261 loggerContextListenerList.add(listener);
262 }
263
264 public void removeListener(LoggerContextListener listener) {
265 loggerContextListenerList.remove(listener);
266 }
267
268 private void resetListenersExceptResetResistant() {
269 List<LoggerContextListener> toRetain = new ArrayList<LoggerContextListener>();
270
271 for (LoggerContextListener lcl : loggerContextListenerList) {
272 if (lcl.isResetResistant()) {
273 toRetain.add(lcl);
274 }
275 }
276 loggerContextListenerList.retainAll(toRetain);
277 }
278
279 private void resetAllListeners() {
280 loggerContextListenerList.clear();
281 }
282
283 public List<LoggerContextListener> getCopyOfListenerList() {
284 return new ArrayList<LoggerContextListener>(loggerContextListenerList);
285 }
286
287 private void fireOnReset() {
288 for (LoggerContextListener listener : loggerContextListenerList) {
289 listener.onReset(this);
290 }
291 }
292
293 private void fireOnStart() {
294 for (LoggerContextListener listener : loggerContextListenerList) {
295 listener.onStart(this);
296 }
297 }
298
299 private void fireOnStop() {
300 for (LoggerContextListener listener : loggerContextListenerList) {
301 listener.onStop(this);
302 }
303 }
304
305
306
307 public boolean isStarted() {
308 return started;
309 }
310
311 public void start() {
312 started = true;
313 fireOnStart();
314 }
315
316 public void stop() {
317 reset();
318 fireOnStop();
319 resetAllListeners();
320 started = false;
321 }
322
323 @Override
324 public String toString() {
325 return this.getClass().getName() + "[" + getName() + "]";
326 }
327 }