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