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