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.ObjectStreamException;
20 import java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.logging.log4j.Level;
27 import org.apache.logging.log4j.Marker;
28 import org.apache.logging.log4j.core.config.Configuration;
29 import org.apache.logging.log4j.core.config.LoggerConfig;
30 import org.apache.logging.log4j.core.config.ReliabilityStrategy;
31 import org.apache.logging.log4j.core.filter.CompositeFilter;
32 import org.apache.logging.log4j.message.Message;
33 import org.apache.logging.log4j.message.MessageFactory;
34 import org.apache.logging.log4j.message.SimpleMessage;
35 import org.apache.logging.log4j.spi.AbstractLogger;
36 import org.apache.logging.log4j.util.Strings;
37 import org.apache.logging.log4j.util.Supplier;
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class Logger extends AbstractLogger implements Supplier<LoggerConfig> {
52
53 private static final long serialVersionUID = 1L;
54
55
56
57
58 protected volatile PrivateConfig privateConfig;
59
60
61 private final LoggerContext context;
62
63
64
65
66
67
68
69
70 protected Logger(final LoggerContext context, final String name, final MessageFactory messageFactory) {
71 super(name, messageFactory);
72 this.context = context;
73 privateConfig = new PrivateConfig(context.getConfiguration(), this);
74 }
75
76 protected Object writeReplace() throws ObjectStreamException {
77 return new LoggerProxy(getName(), getMessageFactory());
78 }
79
80
81
82
83
84
85
86 public Logger getParent() {
87 final LoggerConfig lc = privateConfig.loggerConfig.getName().equals(getName()) ? privateConfig.loggerConfig
88 .getParent() : privateConfig.loggerConfig;
89 if (lc == null) {
90 return null;
91 }
92 final String lcName = lc.getName();
93 final MessageFactory messageFactory = getMessageFactory();
94 if (context.hasLogger(lcName, messageFactory)) {
95 return context.getLogger(lcName, messageFactory);
96 }
97 return new Logger(context, lcName, messageFactory);
98 }
99
100
101
102
103
104
105 public LoggerContext getContext() {
106 return context;
107 }
108
109
110
111
112
113
114
115
116
117 public synchronized void setLevel(final Level level) {
118 if (level == getLevel()) {
119 return;
120 }
121 Level actualLevel;
122 if (level != null) {
123 actualLevel = level;
124 } else {
125 final Logger parent = getParent();
126 actualLevel = parent != null ? parent.getLevel() : privateConfig.loggerConfigLevel;
127 }
128 privateConfig = new PrivateConfig(privateConfig, actualLevel);
129 }
130
131
132
133
134
135
136 @Override
137 public LoggerConfig get() {
138 return privateConfig.loggerConfig;
139 }
140
141 @Override
142 public void logMessage(final String fqcn, final Level level, final Marker marker, final Message message,
143 final Throwable t) {
144 final Message msg = message == null ? new SimpleMessage(Strings.EMPTY) : message;
145
146 final ReliabilityStrategy strategy = privateConfig.loggerConfig.getReliabilityStrategy();
147 strategy.log(this, getName(), fqcn, marker, level, msg, t);
148 }
149
150 @Override
151 public boolean isEnabled(final Level level, final Marker marker, final String message, final Throwable t) {
152 return privateConfig.filter(level, marker, message, t);
153 }
154
155 @Override
156 public boolean isEnabled(final Level level, final Marker marker, final String message) {
157 return privateConfig.filter(level, marker, message);
158 }
159
160 @Override
161 public boolean isEnabled(final Level level, final Marker marker, final String message, final Object... params) {
162 return privateConfig.filter(level, marker, message, params);
163 }
164
165 @Override
166 public boolean isEnabled(final Level level, final Marker marker, final Object message, final Throwable t) {
167 return privateConfig.filter(level, marker, message, t);
168 }
169
170 @Override
171 public boolean isEnabled(final Level level, final Marker marker, final Message message, final Throwable t) {
172 return privateConfig.filter(level, marker, message, t);
173 }
174
175
176
177
178
179
180 public void addAppender(final Appender appender) {
181 privateConfig.config.addLoggerAppender(this, appender);
182 }
183
184
185
186
187
188
189 public void removeAppender(final Appender appender) {
190 privateConfig.loggerConfig.removeAppender(appender.getName());
191 }
192
193
194
195
196
197
198 public Map<String, Appender> getAppenders() {
199 return privateConfig.loggerConfig.getAppenders();
200 }
201
202
203
204
205
206
207
208 public Iterator<Filter> getFilters() {
209 final Filter filter = privateConfig.loggerConfig.getFilter();
210 if (filter == null) {
211 return new ArrayList<Filter>().iterator();
212 } else if (filter instanceof CompositeFilter) {
213 return ((CompositeFilter) filter).iterator();
214 } else {
215 final List<Filter> filters = new ArrayList<>();
216 filters.add(filter);
217 return filters.iterator();
218 }
219 }
220
221
222
223
224
225
226 @Override
227 public Level getLevel() {
228 return privateConfig.loggerConfigLevel;
229 }
230
231
232
233
234
235
236 public int filterCount() {
237 final Filter filter = privateConfig.loggerConfig.getFilter();
238 if (filter == null) {
239 return 0;
240 } else if (filter instanceof CompositeFilter) {
241 return ((CompositeFilter) filter).size();
242 }
243 return 1;
244 }
245
246
247
248
249
250
251 public void addFilter(final Filter filter) {
252 privateConfig.config.addLoggerFilter(this, filter);
253 }
254
255
256
257
258
259
260
261 public boolean isAdditive() {
262 return privateConfig.loggerConfig.isAdditive();
263 }
264
265
266
267
268
269
270
271 public void setAdditive(final boolean additive) {
272 privateConfig.config.setLoggerAdditive(this, additive);
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 protected void updateConfiguration(final Configuration newConfig) {
293 this.privateConfig = new PrivateConfig(newConfig, this);
294 }
295
296
297
298
299 protected class PrivateConfig {
300
301
302 public final LoggerConfig loggerConfig;
303
304 public final Configuration config;
305 private final Level loggerConfigLevel;
306 private final int intLevel;
307 private final Logger logger;
308
309 public PrivateConfig(final Configuration config, final Logger logger) {
310 this.config = config;
311 this.loggerConfig = config.getLoggerConfig(getName());
312 this.loggerConfigLevel = this.loggerConfig.getLevel();
313 this.intLevel = this.loggerConfigLevel.intLevel();
314 this.logger = logger;
315 }
316
317 public PrivateConfig(final PrivateConfig pc, final Level level) {
318 this.config = pc.config;
319 this.loggerConfig = pc.loggerConfig;
320 this.loggerConfigLevel = level;
321 this.intLevel = this.loggerConfigLevel.intLevel();
322 this.logger = pc.logger;
323 }
324
325 public PrivateConfig(final PrivateConfig pc, final LoggerConfig lc) {
326 this.config = pc.config;
327 this.loggerConfig = lc;
328 this.loggerConfigLevel = lc.getLevel();
329 this.intLevel = this.loggerConfigLevel.intLevel();
330 this.logger = pc.logger;
331 }
332
333
334 public void logEvent(final LogEvent event) {
335 loggerConfig.log(event);
336 }
337
338 boolean filter(final Level level, final Marker marker, final String msg) {
339 final Filter filter = config.getFilter();
340 if (filter != null) {
341 final Filter.Result r = filter.filter(logger, level, marker, msg);
342 if (r != Filter.Result.NEUTRAL) {
343 return r == Filter.Result.ACCEPT;
344 }
345 }
346 return level != null && intLevel >= level.intLevel();
347 }
348
349 boolean filter(final Level level, final Marker marker, final String msg, final Throwable t) {
350 final Filter filter = config.getFilter();
351 if (filter != null) {
352 final Filter.Result r = filter.filter(logger, level, marker, msg, t);
353 if (r != Filter.Result.NEUTRAL) {
354 return r == Filter.Result.ACCEPT;
355 }
356 }
357 return level != null && intLevel >= level.intLevel();
358 }
359
360 boolean filter(final Level level, final Marker marker, final String msg, final Object... p1) {
361 final Filter filter = config.getFilter();
362 if (filter != null) {
363 final Filter.Result r = filter.filter(logger, level, marker, msg, p1);
364 if (r != Filter.Result.NEUTRAL) {
365 return r == Filter.Result.ACCEPT;
366 }
367 }
368 return level != null && intLevel >= level.intLevel();
369 }
370
371 boolean filter(final Level level, final Marker marker, final Object msg, final Throwable t) {
372 final Filter filter = config.getFilter();
373 if (filter != null) {
374 final Filter.Result r = filter.filter(logger, level, marker, msg, t);
375 if (r != Filter.Result.NEUTRAL) {
376 return r == Filter.Result.ACCEPT;
377 }
378 }
379 return level != null && intLevel >= level.intLevel();
380 }
381
382 boolean filter(final Level level, final Marker marker, final Message msg, final Throwable t) {
383 final Filter filter = config.getFilter();
384 if (filter != null) {
385 final Filter.Result r = filter.filter(logger, level, marker, msg, t);
386 if (r != Filter.Result.NEUTRAL) {
387 return r == Filter.Result.ACCEPT;
388 }
389 }
390 return level != null && intLevel >= level.intLevel();
391 }
392 }
393
394
395
396
397
398
399
400 protected static class LoggerProxy implements Serializable {
401 private static final long serialVersionUID = 1L;
402
403 private final String name;
404 private final MessageFactory messageFactory;
405
406 public LoggerProxy(String name, MessageFactory messageFactory) {
407 this.name = name;
408 this.messageFactory = messageFactory;
409 }
410
411 protected Object readResolve() throws ObjectStreamException {
412 return new Logger(LoggerContext.getContext(), name, messageFactory);
413 }
414 }
415
416
417
418
419
420
421 @Override
422 public String toString() {
423 final String nameLevel = Strings.EMPTY + getName() + ':' + getLevel();
424 if (context == null) {
425 return nameLevel;
426 }
427 final String contextName = context.getName();
428 return contextName == null ? nameLevel : nameLevel + " in " + contextName;
429 }
430
431 @Override
432 public boolean equals(final Object o) {
433 if (this == o) {
434 return true;
435 }
436 if (o == null || getClass() != o.getClass()) {
437 return false;
438 }
439 final Logger that = (Logger) o;
440 return getName().equals(that.getName());
441 }
442
443 @Override
444 public int hashCode() {
445 return getName().hashCode();
446 }
447 }