1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core;
18
19 import org.apache.logging.log4j.core.config.Configuration;
20 import org.apache.logging.log4j.core.config.ConfigurationFactory;
21 import org.apache.logging.log4j.core.config.ConfigurationListener;
22 import org.apache.logging.log4j.core.config.DefaultConfiguration;
23 import org.apache.logging.log4j.core.config.NullConfiguration;
24 import org.apache.logging.log4j.core.config.Reconfigurable;
25 import org.apache.logging.log4j.status.StatusLogger;
26
27 import java.io.File;
28 import java.net.URI;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.concurrent.ConcurrentMap;
31 import java.util.concurrent.locks.Lock;
32 import java.util.concurrent.locks.ReentrantLock;
33
34
35
36
37
38
39 public class LoggerContext implements org.apache.logging.log4j.spi.LoggerContext, ConfigurationListener, LifeCycle {
40
41 private static final StatusLogger logger = StatusLogger.getLogger();
42
43 private final ConcurrentMap<String, Logger> loggers = new ConcurrentHashMap<String, Logger>();
44
45
46
47
48
49 private volatile Configuration config = new DefaultConfiguration();
50
51 private Object externalContext;
52
53 private final String name;
54
55 private final URI configLocation;
56
57
58
59
60 public enum Status {
61
62 INITIALIZED,
63
64 STARTING,
65
66 STARTED,
67
68 STOPPING,
69
70 STOPPED
71 }
72
73 private volatile Status status = Status.INITIALIZED;
74
75 private final Lock configLock = new ReentrantLock();
76
77
78
79
80
81 public LoggerContext(String name) {
82 this(name, null, (URI) null);
83 }
84
85
86
87
88
89
90 public LoggerContext(String name, Object externalContext) {
91 this(name, externalContext, (URI) null);
92 }
93
94
95
96
97
98
99
100 public LoggerContext(String name, Object externalContext, URI configLocn) {
101 this.name = name;
102 this.externalContext = externalContext;
103 this.configLocation = configLocn;
104 }
105
106
107
108
109
110
111
112
113 public LoggerContext(String name, Object externalContext, String configLocn) {
114 this.name = name;
115 this.externalContext = externalContext;
116 if (configLocn != null) {
117 URI uri;
118 try {
119 uri = new File(configLocn).toURI();
120 } catch (Exception ex) {
121 uri = null;
122 }
123 configLocation = uri;
124 } else {
125 configLocation = null;
126 }
127 }
128
129 public void start() {
130 if (configLock.tryLock()) {
131 try {
132 if (status == Status.INITIALIZED) {
133 status = Status.STARTING;
134 reconfigure();
135 status = Status.STARTED;
136 }
137 } finally {
138 configLock.unlock();
139 }
140 }
141 }
142
143 public void stop() {
144 configLock.lock();
145 try {
146 status = Status.STOPPING;
147 updateLoggers(new NullConfiguration());
148 config.stop();
149 externalContext = null;
150 status = Status.STOPPED;
151 } finally {
152 configLock.unlock();
153 }
154 }
155
156
157
158
159
160
161 public String getName() {
162 return name;
163 }
164
165 public Status getStatus() {
166 return status;
167 }
168
169 public boolean isStarted() {
170 return status == Status.STARTED;
171 }
172
173
174
175
176
177 public void setExternalContext(Object context) {
178 this.externalContext = context;
179 }
180
181
182
183
184
185 public Object getExternalContext() {
186 return this.externalContext;
187 }
188
189
190
191
192
193
194 public Logger getLogger(String name) {
195
196 Logger logger = loggers.get(name);
197 if (logger != null) {
198 return logger;
199 }
200
201 logger = newInstance(this, name);
202 Logger prev = loggers.putIfAbsent(name, logger);
203 return prev == null ? logger : prev;
204 }
205
206
207
208
209
210
211 public boolean hasLogger(String name) {
212 return loggers.containsKey(name);
213 }
214
215
216
217
218
219 public Configuration getConfiguration() {
220 return config;
221 }
222
223
224
225
226
227
228 public void addFilter(Filter filter) {
229 config.addFilter(filter);
230 }
231
232
233
234
235
236 public void removeFiler(Filter filter) {
237 config.removeFilter(filter);
238 }
239
240
241
242
243
244
245 public synchronized Configuration setConfiguration(Configuration config) {
246 if (config == null) {
247 throw new NullPointerException("No Configuration was provided");
248 }
249 Configuration prev = this.config;
250 config.addListener(this);
251 config.start();
252 this.config = config;
253 updateLoggers();
254 if (prev != null) {
255 prev.removeListener(this);
256 prev.stop();
257 }
258 return prev;
259 }
260
261
262
263
264 public synchronized void reconfigure() {
265 logger.debug("Reconfiguration started for context " + name);
266 Configuration instance = ConfigurationFactory.getInstance().getConfiguration(name, configLocation);
267 setConfiguration(instance);
268
269
270
271
272
273
274 logger.debug("Reconfiguration completed");
275 }
276
277
278
279
280 public void updateLoggers() {
281 updateLoggers(this.config);
282 }
283
284
285
286
287
288 public void updateLoggers(Configuration config) {
289 for (Logger logger : loggers.values()) {
290 logger.updateConfiguration(config);
291 }
292 }
293
294
295
296
297
298 public synchronized void onChange(Reconfigurable reconfigurable) {
299 logger.debug("Reconfiguration started for context " + name);
300 Configuration config = reconfigurable.reconfigure();
301 if (config != null) {
302 setConfiguration(config);
303 logger.debug("Reconfiguration completed");
304 } else {
305 logger.debug("Reconfiguration failed");
306 }
307 }
308
309
310 private Logger newInstance(LoggerContext ctx, String name) {
311 return new Logger(ctx, name);
312 }
313
314 }