001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.classic.jul; 015 016import ch.qos.logback.classic.Level; 017import ch.qos.logback.classic.Logger; 018import ch.qos.logback.classic.LoggerContext; 019import ch.qos.logback.classic.spi.LoggerContextListener; 020import ch.qos.logback.core.spi.ContextAwareBase; 021import ch.qos.logback.core.spi.LifeCycle; 022 023import java.util.Enumeration; 024import java.util.HashSet; 025import java.util.List; 026import java.util.Set; 027import java.util.logging.LogManager; 028 029/** 030 * Propagate level changes made to a logback logger into the equivalent logger 031 * in j.u.l. 032 */ 033public class LevelChangePropagator extends ContextAwareBase implements LoggerContextListener, LifeCycle { 034 035 private Set<java.util.logging.Logger> julLoggerSet = new HashSet<java.util.logging.Logger>(); 036 boolean isStarted = false; 037 boolean resetJUL = false; 038 039 public void setResetJUL(boolean resetJUL) { 040 this.resetJUL = resetJUL; 041 } 042 043 public boolean isResetResistant() { 044 return false; 045 } 046 047 public void onStart(LoggerContext context) { 048 } 049 050 public void onReset(LoggerContext context) { 051 } 052 053 public void onStop(LoggerContext context) { 054 } 055 056 public void onLevelChange(Logger logger, Level level) { 057 propagate(logger, level); 058 } 059 060 private void propagate(Logger logger, Level level) { 061 addInfo("Propagating " + level + " level on " + logger + " onto the JUL framework"); 062 java.util.logging.Logger julLogger = JULHelper.asJULLogger(logger); 063 // prevent garbage collection of jul loggers whose level we set 064 // see also http://jira.qos.ch/browse//LOGBACK-404 065 julLoggerSet.add(julLogger); 066 java.util.logging.Level julLevel = JULHelper.asJULLevel(level); 067 julLogger.setLevel(julLevel); 068 } 069 070 public void resetJULLevels() { 071 LogManager lm = LogManager.getLogManager(); 072 073 Enumeration<String> e = lm.getLoggerNames(); 074 while (e.hasMoreElements()) { 075 String loggerName = e.nextElement(); 076 java.util.logging.Logger julLogger = lm.getLogger(loggerName); 077 if (JULHelper.isRegularNonRootLogger(julLogger) && julLogger.getLevel() != null) { 078 addInfo("Setting level of jul logger [" + loggerName + "] to null"); 079 julLogger.setLevel(null); 080 } 081 } 082 } 083 084 private void propagateExistingLoggerLevels() { 085 LoggerContext loggerContext = (LoggerContext) context; 086 List<Logger> loggerList = loggerContext.getLoggerList(); 087 for (Logger l : loggerList) { 088 if (l.getLevel() != null) { 089 propagate(l, l.getLevel()); 090 } 091 } 092 } 093 094 public void start() { 095 if (resetJUL) { 096 resetJULLevels(); 097 } 098 propagateExistingLoggerLevels(); 099 100 isStarted = true; 101 } 102 103 public void stop() { 104 isStarted = false; 105 } 106 107 public boolean isStarted() { 108 return isStarted; 109 } 110}