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