1 /**
2  * Logback: the reliable, generic, fast and flexible logging framework.
3  * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4  *
5  * This program and the accompanying materials are dual-licensed under
6  * either the terms of the Eclipse Public License v1.0 as published by
7  * the Eclipse Foundation
8  *
9  *   or (per the licensee's choosing)
10  *
11  * under the terms of the GNU Lesser General Public License version 2.1
12  * as published by the Free Software Foundation.
13  */

14 package ch.qos.logback.classic.jul;
15
16 import ch.qos.logback.classic.Level;
17 import ch.qos.logback.classic.Logger;
18 import ch.qos.logback.classic.LoggerContext;
19 import ch.qos.logback.classic.spi.LoggerContextListener;
20 import ch.qos.logback.core.spi.ContextAwareBase;
21 import ch.qos.logback.core.spi.LifeCycle;
22
23 import java.util.Enumeration;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.logging.LogManager;
28
29 /**
30  * Propagate level changes made to a logback logger into the equivalent logger in j.u.l.
31  */

32 public class LevelChangePropagator extends ContextAwareBase implements LoggerContextListener, LifeCycle {
33
34     private Set<java.util.logging.Logger> julLoggerSet = new HashSet<java.util.logging.Logger>();
35     boolean isStarted = false;
36     boolean resetJUL = false;
37
38     public void setResetJUL(boolean resetJUL) {
39         this.resetJUL = resetJUL;
40     }
41
42     public boolean isResetResistant() {
43         return false;
44     }
45
46     public void onStart(LoggerContext context) {
47     }
48
49     public void onReset(LoggerContext context) {
50     }
51
52     public void onStop(LoggerContext context) {
53     }
54
55     public void onLevelChange(Logger logger, Level level) {
56         propagate(logger, level);
57     }
58
59     private void propagate(Logger logger, Level level) {
60         addInfo("Propagating " + level + " level on " + logger + " onto the JUL framework");
61         java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger);
62         // prevent garbage collection of jul loggers whose level we set
63         // see also http://jira.qos.ch/browse/LBCLASSIC-256
64         julLoggerSet.add(julLogger);
65         java.util.logging.Level julLevel = JULHelper.asJULLevel(level);
66         julLogger.setLevel(julLevel);
67     }
68
69     public void resetJULLevels() {
70         LogManager lm = LogManager.getLogManager();
71
72         Enumeration<String> e = lm.getLoggerNames();
73         while (e.hasMoreElements()) {
74             String loggerName = e.nextElement();
75             java.util.logging.Logger julLogger = lm.getLogger(loggerName);
76             if (JULHelper.isRegularNonRootLogger(julLogger) && julLogger.getLevel() != null) {
77                 addInfo("Setting level of jul logger [" + loggerName + "] to null");
78                 julLogger.setLevel(null);
79             }
80         }
81     }
82
83     private void propagateExistingLoggerLevels() {
84         LoggerContext loggerContext = (LoggerContext) context;
85         List<Logger> loggerList = loggerContext.getLoggerList();
86         for (Logger l : loggerList) {
87             if (l.getLevel() != null) {
88                 propagate(l, l.getLevel());
89             }
90         }
91     }
92
93     public void start() {
94         if (resetJUL) {
95             resetJULLevels();
96         }
97         propagateExistingLoggerLevels();
98
99         isStarted = true;
100     }
101
102     public void stop() {
103         isStarted = false;
104     }
105
106     public boolean isStarted() {
107         return isStarted;
108     }
109 }
110