1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic;
15
16 import java.io.ObjectStreamException;
17 import java.io.Serializable;
18 import java.util.Collections;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.concurrent.CopyOnWriteArrayList;
22
23 import org.slf4j.LoggerFactory;
24 import org.slf4j.Marker;
25 import org.slf4j.spi.LocationAwareLogger;
26
27 import ch.qos.logback.classic.spi.ILoggingEvent;
28 import ch.qos.logback.classic.spi.LoggingEvent;
29 import ch.qos.logback.classic.util.LoggerNameUtil;
30 import ch.qos.logback.core.Appender;
31 import ch.qos.logback.core.CoreConstants;
32 import ch.qos.logback.core.spi.AppenderAttachable;
33 import ch.qos.logback.core.spi.AppenderAttachableImpl;
34 import ch.qos.logback.core.spi.FilterReply;
35
36 public final class Logger implements org.slf4j.Logger, LocationAwareLogger, AppenderAttachable<ILoggingEvent>, Serializable {
37
38 private static final long serialVersionUID = 5454405123156820674L;
39
40
41
42
43
44 public static final String FQCN = ch.qos.logback.classic.Logger.class.getName();
45
46
47
48
49 private String name;
50
51
52 transient private Level level;
53
54
55
56 transient private int effectiveLevelInt;
57
58
59
60
61
62 transient private Logger parent;
63
64
65
66
67 transient private List<Logger> childrenList;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 transient private AppenderAttachableImpl<ILoggingEvent> aai;
90
91
92
93
94
95
96
97
98 transient private boolean additive = true;
99
100 final transient LoggerContext loggerContext;
101
102 Logger(String name, Logger parent, LoggerContext loggerContext) {
103 this.name = name;
104 this.parent = parent;
105 this.loggerContext = loggerContext;
106 }
107
108 public Level getEffectiveLevel() {
109 return Level.toLevel(effectiveLevelInt);
110 }
111
112 int getEffectiveLevelInt() {
113 return effectiveLevelInt;
114 }
115
116 public Level getLevel() {
117 return level;
118 }
119
120 public String getName() {
121 return name;
122 }
123
124 private boolean isRootLogger() {
125
126 return parent == null;
127 }
128
129 Logger getChildByName(final String childName) {
130 if (childrenList == null) {
131 return null;
132 } else {
133 int len = this.childrenList.size();
134 for (int i = 0; i < len; i++) {
135 final Logger childLogger_i = (Logger) childrenList.get(i);
136 final String childName_i = childLogger_i.getName();
137
138 if (childName.equals(childName_i)) {
139 return childLogger_i;
140 }
141 }
142
143 return null;
144 }
145 }
146
147 public synchronized void setLevel(Level newLevel) {
148 if (level == newLevel) {
149
150 return;
151 }
152 if (newLevel == null && isRootLogger()) {
153 throw new IllegalArgumentException("The level of the root logger cannot be set to null");
154 }
155
156 level = newLevel;
157 if (newLevel == null) {
158 effectiveLevelInt = parent.effectiveLevelInt;
159 newLevel = parent.getEffectiveLevel();
160 } else {
161 effectiveLevelInt = newLevel.levelInt;
162 }
163
164 if (childrenList != null) {
165 int len = childrenList.size();
166 for (int i = 0; i < len; i++) {
167 Logger child = (Logger) childrenList.get(i);
168
169 child.handleParentLevelChange(effectiveLevelInt);
170 }
171 }
172
173 loggerContext.fireOnLevelChange(this, newLevel);
174 }
175
176
177
178
179
180
181
182 private synchronized void handleParentLevelChange(int newParentLevelInt) {
183
184
185 if (level == null) {
186 effectiveLevelInt = newParentLevelInt;
187
188
189 if (childrenList != null) {
190 int len = childrenList.size();
191 for (int i = 0; i < len; i++) {
192 Logger child = (Logger) childrenList.get(i);
193 child.handleParentLevelChange(newParentLevelInt);
194 }
195 }
196 }
197 }
198
199
200
201
202
203
204 public void detachAndStopAllAppenders() {
205 if (aai != null) {
206 aai.detachAndStopAllAppenders();
207 }
208 }
209
210 public boolean detachAppender(String name) {
211 if (aai == null) {
212 return false;
213 }
214 return aai.detachAppender(name);
215 }
216
217
218
219 public synchronized void addAppender(Appender<ILoggingEvent> newAppender) {
220 if (aai == null) {
221 aai = new AppenderAttachableImpl<ILoggingEvent>();
222 }
223 aai.addAppender(newAppender);
224 }
225
226 public boolean isAttached(Appender<ILoggingEvent> appender) {
227 if (aai == null) {
228 return false;
229 }
230 return aai.isAttached(appender);
231 }
232
233 @SuppressWarnings("unchecked")
234 public Iterator<Appender<ILoggingEvent>> iteratorForAppenders() {
235 if (aai == null) {
236 return Collections.EMPTY_LIST.iterator();
237 }
238 return aai.iteratorForAppenders();
239 }
240
241 public Appender<ILoggingEvent> getAppender(String name) {
242 if (aai == null) {
243 return null;
244 }
245 return aai.getAppender(name);
246 }
247
248
249
250
251
252
253
254 public void callAppenders(ILoggingEvent event) {
255 int writes = 0;
256 for (Logger l = this; l != null; l = l.parent) {
257 writes += l.appendLoopOnAppenders(event);
258 if (!l.additive) {
259 break;
260 }
261 }
262
263 if (writes == 0) {
264 loggerContext.noAppenderDefinedWarning(this);
265 }
266 }
267
268 private int appendLoopOnAppenders(ILoggingEvent event) {
269 if (aai != null) {
270 return aai.appendLoopOnAppenders(event);
271 } else {
272 return 0;
273 }
274 }
275
276
277
278
279 public boolean detachAppender(Appender<ILoggingEvent> appender) {
280 if (aai == null) {
281 return false;
282 }
283 return aai.detachAppender(appender);
284 }
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 Logger createChildByLastNamePart(final String lastPart) {
302 int i_index = LoggerNameUtil.getFirstSeparatorIndexOf(lastPart);
303 if (i_index != -1) {
304 throw new IllegalArgumentException("Child name [" + lastPart + " passed as parameter, may not include [" + CoreConstants.DOT + "]");
305 }
306
307 if (childrenList == null) {
308 childrenList = new CopyOnWriteArrayList<Logger>();
309 }
310 Logger childLogger;
311 if (this.isRootLogger()) {
312 childLogger = new Logger(lastPart, this, this.loggerContext);
313 } else {
314 childLogger = new Logger(name + CoreConstants.DOT + lastPart, this, this.loggerContext);
315 }
316 childrenList.add(childLogger);
317 childLogger.effectiveLevelInt = this.effectiveLevelInt;
318 return childLogger;
319 }
320
321 private void localLevelReset() {
322 effectiveLevelInt = Level.DEBUG_INT;
323 if (isRootLogger()) {
324 level = Level.DEBUG;
325 } else {
326 level = null;
327 }
328 }
329
330 void recursiveReset() {
331 detachAndStopAllAppenders();
332 localLevelReset();
333 additive = true;
334 if (childrenList == null) {
335 return;
336 }
337 for (Logger childLogger : childrenList) {
338 childLogger.recursiveReset();
339 }
340 }
341
342
343
344
345
346
347 Logger createChildByName(final String childName) {
348 int i_index = LoggerNameUtil.getSeparatorIndexOf(childName, this.name.length() + 1);
349 if (i_index != -1) {
350 throw new IllegalArgumentException("For logger [" + this.name + "] child name [" + childName
351 + " passed as parameter, may not include '.' after index" + (this.name.length() + 1));
352 }
353
354 if (childrenList == null) {
355 childrenList = new CopyOnWriteArrayList<Logger>();
356 }
357 Logger childLogger;
358 childLogger = new Logger(childName, this, this.loggerContext);
359 childrenList.add(childLogger);
360 childLogger.effectiveLevelInt = this.effectiveLevelInt;
361 return childLogger;
362 }
363
364
365
366
367
368
369
370 private void filterAndLog_0_Or3Plus(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params,
371 final Throwable t) {
372
373 final FilterReply decision = loggerContext.getTurboFilterChainDecision_0_3OrMore(marker, this, level, msg, params, t);
374
375 if (decision == FilterReply.NEUTRAL) {
376 if (effectiveLevelInt > level.levelInt) {
377 return;
378 }
379 } else if (decision == FilterReply.DENY) {
380 return;
381 }
382
383 buildLoggingEventAndAppend(localFQCN, marker, level, msg, params, t);
384 }
385
386 private void filterAndLog_1(final String localFQCN, final Marker marker, final Level level, final String msg, final Object param, final Throwable t) {
387
388 final FilterReply decision = loggerContext.getTurboFilterChainDecision_1(marker, this, level, msg, param, t);
389
390 if (decision == FilterReply.NEUTRAL) {
391 if (effectiveLevelInt > level.levelInt) {
392 return;
393 }
394 } else if (decision == FilterReply.DENY) {
395 return;
396 }
397
398 buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[] { param }, t);
399 }
400
401 private void filterAndLog_2(final String localFQCN, final Marker marker, final Level level, final String msg, final Object param1, final Object param2,
402 final Throwable t) {
403
404 final FilterReply decision = loggerContext.getTurboFilterChainDecision_2(marker, this, level, msg, param1, param2, t);
405
406 if (decision == FilterReply.NEUTRAL) {
407 if (effectiveLevelInt > level.levelInt) {
408 return;
409 }
410 } else if (decision == FilterReply.DENY) {
411 return;
412 }
413
414 buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[] { param1, param2 }, t);
415 }
416
417 private void buildLoggingEventAndAppend(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params,
418 final Throwable t) {
419 LoggingEvent le = new LoggingEvent(localFQCN, this, level, msg, t, params);
420 le.setMarker(marker);
421 callAppenders(le);
422 }
423
424 public void trace(String msg) {
425 filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, msg, null, null);
426 }
427
428 public void trace(String format, Object arg) {
429 filterAndLog_1(FQCN, null, Level.TRACE, format, arg, null);
430 }
431
432 public void trace(String format, Object arg1, Object arg2) {
433 filterAndLog_2(FQCN, null, Level.TRACE, format, arg1, arg2, null);
434 }
435
436 public void trace(String format, Object... argArray) {
437 filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, format, argArray, null);
438 }
439
440 public void trace(String msg, Throwable t) {
441 filterAndLog_0_Or3Plus(FQCN, null, Level.TRACE, msg, null, t);
442 }
443
444 public void trace(Marker marker, String msg) {
445 filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, msg, null, null);
446 }
447
448 public void trace(Marker marker, String format, Object arg) {
449 filterAndLog_1(FQCN, marker, Level.TRACE, format, arg, null);
450 }
451
452 public void trace(Marker marker, String format, Object arg1, Object arg2) {
453 filterAndLog_2(FQCN, marker, Level.TRACE, format, arg1, arg2, null);
454 }
455
456 public void trace(Marker marker, String format, Object... argArray) {
457 filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, format, argArray, null);
458 }
459
460 public void trace(Marker marker, String msg, Throwable t) {
461 filterAndLog_0_Or3Plus(FQCN, marker, Level.TRACE, msg, null, t);
462 }
463
464 public boolean isDebugEnabled() {
465 return isDebugEnabled(null);
466 }
467
468 public boolean isDebugEnabled(Marker marker) {
469 final FilterReply decision = callTurboFilters(marker, Level.DEBUG);
470 if (decision == FilterReply.NEUTRAL) {
471 return effectiveLevelInt <= Level.DEBUG_INT;
472 } else if (decision == FilterReply.DENY) {
473 return false;
474 } else if (decision == FilterReply.ACCEPT) {
475 return true;
476 } else {
477 throw new IllegalStateException("Unknown FilterReply value: " + decision);
478 }
479 }
480
481 public void debug(String msg) {
482 filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, msg, null, null);
483 }
484
485 public void debug(String format, Object arg) {
486 filterAndLog_1(FQCN, null, Level.DEBUG, format, arg, null);
487 }
488
489 public void debug(String format, Object arg1, Object arg2) {
490 filterAndLog_2(FQCN, null, Level.DEBUG, format, arg1, arg2, null);
491 }
492
493 public void debug(String format, Object... argArray) {
494 filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, format, argArray, null);
495 }
496
497 public void debug(String msg, Throwable t) {
498 filterAndLog_0_Or3Plus(FQCN, null, Level.DEBUG, msg, null, t);
499 }
500
501 public void debug(Marker marker, String msg) {
502 filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, msg, null, null);
503 }
504
505 public void debug(Marker marker, String format, Object arg) {
506 filterAndLog_1(FQCN, marker, Level.DEBUG, format, arg, null);
507 }
508
509 public void debug(Marker marker, String format, Object arg1, Object arg2) {
510 filterAndLog_2(FQCN, marker, Level.DEBUG, format, arg1, arg2, null);
511 }
512
513 public void debug(Marker marker, String format, Object... argArray) {
514 filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, format, argArray, null);
515 }
516
517 public void debug(Marker marker, String msg, Throwable t) {
518 filterAndLog_0_Or3Plus(FQCN, marker, Level.DEBUG, msg, null, t);
519 }
520
521 public void error(String msg) {
522 filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, msg, null, null);
523 }
524
525 public void error(String format, Object arg) {
526 filterAndLog_1(FQCN, null, Level.ERROR, format, arg, null);
527 }
528
529 public void error(String format, Object arg1, Object arg2) {
530 filterAndLog_2(FQCN, null, Level.ERROR, format, arg1, arg2, null);
531 }
532
533 public void error(String format, Object... argArray) {
534 filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, format, argArray, null);
535 }
536
537 public void error(String msg, Throwable t) {
538 filterAndLog_0_Or3Plus(FQCN, null, Level.ERROR, msg, null, t);
539 }
540
541 public void error(Marker marker, String msg) {
542 filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, msg, null, null);
543 }
544
545 public void error(Marker marker, String format, Object arg) {
546 filterAndLog_1(FQCN, marker, Level.ERROR, format, arg, null);
547 }
548
549 public void error(Marker marker, String format, Object arg1, Object arg2) {
550 filterAndLog_2(FQCN, marker, Level.ERROR, format, arg1, arg2, null);
551 }
552
553 public void error(Marker marker, String format, Object... argArray) {
554 filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, format, argArray, null);
555 }
556
557 public void error(Marker marker, String msg, Throwable t) {
558 filterAndLog_0_Or3Plus(FQCN, marker, Level.ERROR, msg, null, t);
559 }
560
561 public boolean isInfoEnabled() {
562 return isInfoEnabled(null);
563 }
564
565 public boolean isInfoEnabled(Marker marker) {
566 FilterReply decision = callTurboFilters(marker, Level.INFO);
567 if (decision == FilterReply.NEUTRAL) {
568 return effectiveLevelInt <= Level.INFO_INT;
569 } else if (decision == FilterReply.DENY) {
570 return false;
571 } else if (decision == FilterReply.ACCEPT) {
572 return true;
573 } else {
574 throw new IllegalStateException("Unknown FilterReply value: " + decision);
575 }
576 }
577
578 public void info(String msg) {
579 filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, msg, null, null);
580 }
581
582 public void info(String format, Object arg) {
583 filterAndLog_1(FQCN, null, Level.INFO, format, arg, null);
584 }
585
586 public void info(String format, Object arg1, Object arg2) {
587 filterAndLog_2(FQCN, null, Level.INFO, format, arg1, arg2, null);
588 }
589
590 public void info(String format, Object... argArray) {
591 filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, format, argArray, null);
592 }
593
594 public void info(String msg, Throwable t) {
595 filterAndLog_0_Or3Plus(FQCN, null, Level.INFO, msg, null, t);
596 }
597
598 public void info(Marker marker, String msg) {
599 filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, msg, null, null);
600 }
601
602 public void info(Marker marker, String format, Object arg) {
603 filterAndLog_1(FQCN, marker, Level.INFO, format, arg, null);
604 }
605
606 public void info(Marker marker, String format, Object arg1, Object arg2) {
607 filterAndLog_2(FQCN, marker, Level.INFO, format, arg1, arg2, null);
608 }
609
610 public void info(Marker marker, String format, Object... argArray) {
611 filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, format, argArray, null);
612 }
613
614 public void info(Marker marker, String msg, Throwable t) {
615 filterAndLog_0_Or3Plus(FQCN, marker, Level.INFO, msg, null, t);
616 }
617
618 public boolean isTraceEnabled() {
619 return isTraceEnabled(null);
620 }
621
622 public boolean isTraceEnabled(Marker marker) {
623 final FilterReply decision = callTurboFilters(marker, Level.TRACE);
624 if (decision == FilterReply.NEUTRAL) {
625 return effectiveLevelInt <= Level.TRACE_INT;
626 } else if (decision == FilterReply.DENY) {
627 return false;
628 } else if (decision == FilterReply.ACCEPT) {
629 return true;
630 } else {
631 throw new IllegalStateException("Unknown FilterReply value: " + decision);
632 }
633 }
634
635 public boolean isErrorEnabled() {
636 return isErrorEnabled(null);
637 }
638
639 public boolean isErrorEnabled(Marker marker) {
640 FilterReply decision = callTurboFilters(marker, Level.ERROR);
641 if (decision == FilterReply.NEUTRAL) {
642 return effectiveLevelInt <= Level.ERROR_INT;
643 } else if (decision == FilterReply.DENY) {
644 return false;
645 } else if (decision == FilterReply.ACCEPT) {
646 return true;
647 } else {
648 throw new IllegalStateException("Unknown FilterReply value: " + decision);
649 }
650 }
651
652 public boolean isWarnEnabled() {
653 return isWarnEnabled(null);
654 }
655
656 public boolean isWarnEnabled(Marker marker) {
657 FilterReply decision = callTurboFilters(marker, Level.WARN);
658 if (decision == FilterReply.NEUTRAL) {
659 return effectiveLevelInt <= Level.WARN_INT;
660 } else if (decision == FilterReply.DENY) {
661 return false;
662 } else if (decision == FilterReply.ACCEPT) {
663 return true;
664 } else {
665 throw new IllegalStateException("Unknown FilterReply value: " + decision);
666 }
667
668 }
669
670 public boolean isEnabledFor(Marker marker, Level level) {
671 FilterReply decision = callTurboFilters(marker, level);
672 if (decision == FilterReply.NEUTRAL) {
673 return effectiveLevelInt <= level.levelInt;
674 } else if (decision == FilterReply.DENY) {
675 return false;
676 } else if (decision == FilterReply.ACCEPT) {
677 return true;
678 } else {
679 throw new IllegalStateException("Unknown FilterReply value: " + decision);
680 }
681 }
682
683 public boolean isEnabledFor(Level level) {
684 return isEnabledFor(null, level);
685 }
686
687 public void warn(String msg) {
688 filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, msg, null, null);
689 }
690
691 public void warn(String msg, Throwable t) {
692 filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, msg, null, t);
693 }
694
695 public void warn(String format, Object arg) {
696 filterAndLog_1(FQCN, null, Level.WARN, format, arg, null);
697 }
698
699 public void warn(String format, Object arg1, Object arg2) {
700 filterAndLog_2(FQCN, null, Level.WARN, format, arg1, arg2, null);
701 }
702
703 public void warn(String format, Object... argArray) {
704 filterAndLog_0_Or3Plus(FQCN, null, Level.WARN, format, argArray, null);
705 }
706
707 public void warn(Marker marker, String msg) {
708 filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, msg, null, null);
709 }
710
711 public void warn(Marker marker, String format, Object arg) {
712 filterAndLog_1(FQCN, marker, Level.WARN, format, arg, null);
713 }
714
715 public void warn(Marker marker, String format, Object... argArray) {
716 filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, format, argArray, null);
717 }
718
719 public void warn(Marker marker, String format, Object arg1, Object arg2) {
720 filterAndLog_2(FQCN, marker, Level.WARN, format, arg1, arg2, null);
721 }
722
723 public void warn(Marker marker, String msg, Throwable t) {
724 filterAndLog_0_Or3Plus(FQCN, marker, Level.WARN, msg, null, t);
725 }
726
727 public boolean isAdditive() {
728 return additive;
729 }
730
731 public void setAdditive(boolean additive) {
732 this.additive = additive;
733 }
734
735 public String toString() {
736 return "Logger[" + name + "]";
737 }
738
739
740
741
742
743
744
745
746
747
748
749
750 private FilterReply callTurboFilters(Marker marker, Level level) {
751 return loggerContext.getTurboFilterChainDecision_0_3OrMore(marker, this, level, null, null, null);
752 }
753
754
755
756
757
758
759 public LoggerContext getLoggerContext() {
760 return loggerContext;
761 }
762
763 public void log(Marker marker, String fqcn, int levelInt, String message, Object[] argArray, Throwable t) {
764 Level level = Level.fromLocationAwareLoggerInteger(levelInt);
765 filterAndLog_0_Or3Plus(fqcn, marker, level, message, argArray, t);
766 }
767
768
769
770
771
772
773 public void log(org.slf4j.event.LoggingEvent slf4jEvent) {
774 Level level = Level.fromLocationAwareLoggerInteger(slf4jEvent.getLevel().toInt());
775 filterAndLog_0_Or3Plus(FQCN, slf4jEvent.getMarker(), level, slf4jEvent.getMessage(), slf4jEvent.getArgumentArray(), slf4jEvent.getThrowable());
776 }
777
778
779
780
781
782
783
784
785
786 protected Object readResolve() throws ObjectStreamException {
787 return LoggerFactory.getLogger(getName());
788 }
789 }