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