Merge branch '1.5.x'
This commit is contained in:
commit
9f3fa648bc
|
@ -35,6 +35,7 @@ import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.ListableBeanFactory;
|
import org.springframework.beans.factory.ListableBeanFactory;
|
||||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.LoggersEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
@ -58,6 +59,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
*
|
*
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
public class EndpointMBeanExporter extends MBeanExporter
|
public class EndpointMBeanExporter extends MBeanExporter
|
||||||
implements SmartLifecycle, ApplicationContextAware {
|
implements SmartLifecycle, ApplicationContextAware {
|
||||||
|
@ -191,6 +193,9 @@ public class EndpointMBeanExporter extends MBeanExporter
|
||||||
if (endpoint instanceof ShutdownEndpoint) {
|
if (endpoint instanceof ShutdownEndpoint) {
|
||||||
return new ShutdownEndpointMBean(beanName, endpoint, this.objectMapper);
|
return new ShutdownEndpointMBean(beanName, endpoint, this.objectMapper);
|
||||||
}
|
}
|
||||||
|
if (endpoint instanceof LoggersEndpoint) {
|
||||||
|
return new LoggersEndpointMBean(beanName, endpoint, this.objectMapper);
|
||||||
|
}
|
||||||
return new DataEndpointMBean(beanName, endpoint, this.objectMapper);
|
return new DataEndpointMBean(beanName, endpoint, this.objectMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.actuate.endpoint.jmx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.LoggersEndpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||||
|
import org.springframework.boot.logging.LogLevel;
|
||||||
|
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||||
|
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||||
|
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapter to expose {@link LoggersEndpoint} as an {@link MvcEndpoint}.
|
||||||
|
*
|
||||||
|
* @author Vedran Pavic
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
@ManagedResource
|
||||||
|
public class LoggersEndpointMBean extends EndpointMBean {
|
||||||
|
|
||||||
|
public LoggersEndpointMBean(String beanName, Endpoint<?> endpoint,
|
||||||
|
ObjectMapper objectMapper) {
|
||||||
|
super(beanName, endpoint, objectMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManagedAttribute(description = "Get log levels for all known loggers")
|
||||||
|
public Object getLoggers() {
|
||||||
|
return convert(getEndpoint().invoke());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManagedOperation(description = "Get log level for a given logger")
|
||||||
|
public Object getLogger(String loggerName) {
|
||||||
|
return convert(getEndpoint().invoke(loggerName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManagedOperation(description = "Set log level for a given logger")
|
||||||
|
public void setLogLevel(String loggerName, String logLevel) {
|
||||||
|
Assert.notNull(logLevel, "LogLevel must not be null");
|
||||||
|
LogLevel level = LogLevel.valueOf(logLevel.toUpperCase());
|
||||||
|
getEndpoint().setLogLevel(loggerName, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoggersEndpoint getEndpoint() {
|
||||||
|
return (LoggersEndpoint) super.getEndpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,18 +26,23 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.management.MBeanException;
|
||||||
import javax.management.MBeanInfo;
|
import javax.management.MBeanInfo;
|
||||||
import javax.management.MalformedObjectNameException;
|
import javax.management.MalformedObjectNameException;
|
||||||
import javax.management.ObjectName;
|
import javax.management.ObjectName;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.LoggersEndpoint;
|
||||||
|
import org.springframework.boot.logging.logback.LogbackLoggingSystem;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.jmx.export.MBeanExporter;
|
import org.springframework.jmx.export.MBeanExporter;
|
||||||
|
@ -45,15 +50,21 @@ import org.springframework.jmx.support.ObjectNameManager;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link EndpointMBeanExporter}
|
* Tests for {@link EndpointMBeanExporter}
|
||||||
*
|
*
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
|
* @author Stephane Nicoll
|
||||||
*/
|
*/
|
||||||
public class EndpointMBeanExporterTests {
|
public class EndpointMBeanExporterTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
GenericApplicationContext context = null;
|
GenericApplicationContext context = null;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -253,6 +264,42 @@ public class EndpointMBeanExporterTests {
|
||||||
assertThat(((List<?>) response).get(0)).isInstanceOf(Long.class);
|
assertThat(((List<?>) response).get(0)).isInstanceOf(Long.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loggerEndpointLowerCaseLogLevel() throws Exception {
|
||||||
|
MBeanExporter mbeanExporter = registerLoggersEndpoint();
|
||||||
|
Object response = mbeanExporter.getServer().invoke(
|
||||||
|
getObjectName("loggersEndpoint", this.context), "setLogLevel",
|
||||||
|
new Object[]{"com.example", "trace"},
|
||||||
|
new String[]{String.class.getName(), String.class.getName()});
|
||||||
|
assertThat(response).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loggerEndpointUnknownLogLevel() throws Exception {
|
||||||
|
MBeanExporter mbeanExporter = registerLoggersEndpoint();
|
||||||
|
this.thrown.expect(MBeanException.class);
|
||||||
|
this.thrown.expectCause(hasMessage(containsString("No enum constant")));
|
||||||
|
this.thrown.expectCause(hasMessage(containsString("LogLevel.INVALID")));
|
||||||
|
mbeanExporter.getServer().invoke(
|
||||||
|
getObjectName("loggersEndpoint", this.context), "setLogLevel",
|
||||||
|
new Object[]{"com.example", "invalid"},
|
||||||
|
new String[]{String.class.getName(), String.class.getName()});
|
||||||
|
}
|
||||||
|
|
||||||
|
private MBeanExporter registerLoggersEndpoint() {
|
||||||
|
this.context = new GenericApplicationContext();
|
||||||
|
this.context.registerBeanDefinition("endpointMbeanExporter",
|
||||||
|
new RootBeanDefinition(EndpointMBeanExporter.class));
|
||||||
|
RootBeanDefinition bd = new RootBeanDefinition(LoggersEndpoint.class);
|
||||||
|
ConstructorArgumentValues values = new ConstructorArgumentValues();
|
||||||
|
values.addIndexedArgumentValue(0,
|
||||||
|
new LogbackLoggingSystem(getClass().getClassLoader()));
|
||||||
|
bd.setConstructorArgumentValues(values);
|
||||||
|
this.context.registerBeanDefinition("loggersEndpoint", bd);
|
||||||
|
this.context.refresh();
|
||||||
|
return this.context.getBean(EndpointMBeanExporter.class);
|
||||||
|
}
|
||||||
|
|
||||||
private ObjectName getObjectName(String beanKey, GenericApplicationContext context)
|
private ObjectName getObjectName(String beanKey, GenericApplicationContext context)
|
||||||
throws MalformedObjectNameException {
|
throws MalformedObjectNameException {
|
||||||
return getObjectName("org.springframework.boot", beanKey, false, context);
|
return getObjectName("org.springframework.boot", beanKey, false, context);
|
||||||
|
|
Loading…
Reference in New Issue