Merge branch '1.1.x'

This commit is contained in:
Andy Wilkinson 2015-01-14 15:08:33 +00:00
commit 0074e9de9d
8 changed files with 164 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,8 +27,10 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
@ -56,6 +58,7 @@ import org.springframework.util.StringUtils;
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @see LoggingSystem#get(ClassLoader)
*/
public class LoggingApplicationListener implements SmartApplicationListener {
@ -95,6 +98,12 @@ public class LoggingApplicationListener implements SmartApplicationListener {
LOG_LEVEL_LOGGERS.add(LogLevel.DEBUG, "org.hibernate.SQL");
}
private static Class<?>[] EVENT_TYPES = { ApplicationStartedEvent.class,
ApplicationEnvironmentPreparedEvent.class, ContextClosedEvent.class };
private static Class<?>[] SOURCE_TYPES = { SpringApplication.class,
ApplicationContext.class };
private final Log logger = LogFactory.getLog(getClass());
private LoggingSystem loggingSystem;
@ -107,13 +116,21 @@ public class LoggingApplicationListener implements SmartApplicationListener {
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationStartedEvent.class.isAssignableFrom(eventType)
|| ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType);
return isAssignableFrom(eventType, EVENT_TYPES);
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
return SpringApplication.class.isAssignableFrom(sourceType);
return isAssignableFrom(sourceType, SOURCE_TYPES);
}
private boolean isAssignableFrom(Class<?> type, Class<?>[] supportedTypes) {
for (Class<?> supportedType : supportedTypes) {
if (supportedType.isAssignableFrom(type)) {
return true;
}
}
return false;
}
@Override
@ -124,6 +141,9 @@ public class LoggingApplicationListener implements SmartApplicationListener {
else if (event instanceof ApplicationEnvironmentPreparedEvent) {
onApplicationPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}
else if (event instanceof ContextClosedEvent) {
onContextClosedEvent();
}
}
private void onApplicationStartedEvent(ApplicationStartedEvent event) {
@ -140,6 +160,12 @@ public class LoggingApplicationListener implements SmartApplicationListener {
initialize(event.getEnvironment(), event.getSpringApplication().getClassLoader());
}
private void onContextClosedEvent() {
if (this.loggingSystem != null) {
this.loggingSystem.cleanUp();
}
}
/**
* Initialize the logging system according to preferences expressed through the
* {@link Environment} and the classpath.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,6 +28,7 @@ import org.springframework.util.StringUtils;
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
*/
public abstract class LoggingSystem {
@ -66,6 +67,14 @@ public abstract class LoggingSystem {
*/
public abstract void initialize(String configLocation, LogFile logFile);
/**
* Clean up the logging system. The default implementation does nothing. Subclasses
* should override this method to perform any logging system-specific cleanup.
*/
public void cleanUp() {
}
/**
* Sets the logging level for a given logger.
* @param loggerName the name of the logger to set

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -36,15 +36,18 @@ public abstract class Slf4JLoggingSystem extends AbstractLoggingSystem {
@Override
public void beforeInitialize() {
super.beforeInitialize();
try {
if (ClassUtils.isPresent(BRIDGE_HANDLER, getClassLoader())) {
try {
SLF4JBridgeHandler.removeHandlersForRootLogger();
configureJdkLoggingBridgeHandler();
}
catch (NoSuchMethodError ex) {
// Method missing in older versions of SLF4J like in JBoss AS 7.1
SLF4JBridgeHandler.uninstall();
@Override
public void cleanUp() {
removeJdkLoggingBridgeHandler();
}
private void configureJdkLoggingBridgeHandler() {
try {
if (bridgeHandlerIsAvailable()) {
removeJdkLoggingBridgeHandler();
SLF4JBridgeHandler.install();
}
}
@ -53,4 +56,25 @@ public abstract class Slf4JLoggingSystem extends AbstractLoggingSystem {
}
}
private boolean bridgeHandlerIsAvailable() {
return ClassUtils.isPresent(BRIDGE_HANDLER, getClassLoader());
}
private void removeJdkLoggingBridgeHandler() {
try {
if (bridgeHandlerIsAvailable()) {
try {
SLF4JBridgeHandler.removeHandlersForRootLogger();
}
catch (NoSuchMethodError ex) {
// Method missing in older versions of SLF4J like in JBoss AS 7.1
SLF4JBridgeHandler.uninstall();
}
}
}
catch (Throwable ex) {
// Ignore and continue
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -36,6 +36,7 @@ import org.springframework.util.StringUtils;
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
*/
public class Log4JLoggingSystem extends Slf4JLoggingSystem {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -42,7 +42,7 @@ import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.spi.FilterReply;
/**
* {@link LoggingSystem} for for <a href="http://logback.qos.ch">logback</a>.
* {@link LoggingSystem} for <a href="http://logback.qos.ch">logback</a>.
*
* @author Phillip Webb
* @author Dave Syer

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,7 +18,9 @@ package org.springframework.boot.logging;
import java.io.File;
import java.io.IOException;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -28,11 +30,13 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.boot.logging.java.JavaLoggingSystem;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.boot.test.OutputCapture;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.support.GenericApplicationContext;
import static org.hamcrest.Matchers.containsString;
@ -46,6 +50,7 @@ import static org.junit.Assert.assertTrue;
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class LoggingApplicationListenerTests {
@ -262,4 +267,22 @@ public class LoggingApplicationListenerTests {
this.logger.debug("testatdebug");
assertThat(this.outputCapture.toString(), not(containsString("testatdebug")));
}
@Test
public void bridgeHandlerLifecycle() throws Exception {
assertTrue(bridgeHandlerInstalled());
this.initializer.onApplicationEvent(new ContextClosedEvent(this.context));
assertFalse(bridgeHandlerInstalled());
}
private boolean bridgeHandlerInstalled() {
Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (Handler handler : handlers) {
if (handler instanceof SLF4JBridgeHandler) {
return true;
}
}
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,12 +17,16 @@
package org.springframework.boot.logging.log4j;
import java.io.File;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import org.apache.commons.logging.impl.Log4JLogger;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.boot.logging.AbstractLoggingSystemTests;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.test.OutputCapture;
@ -37,6 +41,7 @@ import static org.junit.Assert.assertTrue;
* Tests for {@link Log4JLoggingSystem}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
@ -53,6 +58,12 @@ public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
this.logger = new Log4JLogger(getClass().getName());
}
@Override
@After
public void clear() {
this.loggingSystem.cleanUp();
}
@Test
public void noFile() throws Exception {
this.loggingSystem.beforeInitialize();
@ -118,4 +129,24 @@ public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
}
@Test
public void bridgeHandlerLifecycle() {
assertFalse(bridgeHandlerInstalled());
this.loggingSystem.beforeInitialize();
assertTrue(bridgeHandlerInstalled());
this.loggingSystem.cleanUp();
assertFalse(bridgeHandlerInstalled());
}
private boolean bridgeHandlerInstalled() {
java.util.logging.Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (Handler handler : handlers) {
if (handler instanceof SLF4JBridgeHandler) {
return true;
}
}
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,13 +17,17 @@
package org.springframework.boot.logging.logback;
import java.io.File;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.SLF4JLogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.ILoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.boot.logging.AbstractLoggingSystemTests;
import org.springframework.boot.logging.LogLevel;
@ -62,6 +66,12 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
this.logger = new SLF4JLogFactory().getInstance(getClass().getName());
}
@Override
@After
public void clear() {
this.loggingSystem.cleanUp();
}
@Test
public void noFile() throws Exception {
this.loggingSystem.beforeInitialize();
@ -142,4 +152,24 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
assertEquals("slf4j", System.getProperty("org.jboss.logging.provider"));
}
@Test
public void bridgeHandlerLifecycle() {
assertFalse(bridgeHandlerInstalled());
this.loggingSystem.beforeInitialize();
assertTrue(bridgeHandlerInstalled());
this.loggingSystem.cleanUp();
assertFalse(bridgeHandlerInstalled());
}
private boolean bridgeHandlerInstalled() {
java.util.logging.Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (Handler handler : handlers) {
if (handler instanceof SLF4JBridgeHandler) {
return true;
}
}
return false;
}
}