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