Browse Source
Add `LoggersEndpoint` that can enables listing and configuration of log
levels. This actuator builds on top of the `LoggingSystem` abstraction
and implements support for Logback, Log4J2, and JUL. The LoggingSystem
interface is modified to require each implementation to list the
configuration of all loggers as well as an individual logger by name.
The MVC endpoint exposes these behaviors at `GET /loggers` and
`GET /loggers/{name}` (much like the metrics actuator).
In addition `POST /loggers/{name}` allows users to modify the level for a given
logger. This modification is passed to the logging implementation, which
then decides, as an internal implementation detail, what the final outcome
of the modification is (e.g. changing all unconfigured children). Users
are then expected to request the listing of all loggers to see what has
changed internally to the logging system.
Closes gh-7086
pull/7225/head
22 changed files with 1021 additions and 10 deletions
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
/* |
||||
* Copyright 2016-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; |
||||
|
||||
import java.util.Collection; |
||||
import java.util.Collections; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.boot.logging.LogLevel; |
||||
import org.springframework.boot.logging.LoggerConfiguration; |
||||
import org.springframework.boot.logging.LoggingSystem; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* {@link Endpoint} to expose a collection of {@link LoggerConfiguration}s. |
||||
* |
||||
* @author Ben Hale |
||||
* @since 1.5.0 |
||||
*/ |
||||
@ConfigurationProperties(prefix = "endpoints.loggers") |
||||
public class LoggersEndpoint extends AbstractEndpoint<Map<String, Map<String, String>>> { |
||||
|
||||
private final LoggingSystem loggingSystem; |
||||
|
||||
/** |
||||
* Create a new {@link LoggersEndpoint} instance. |
||||
* @param loggingSystem the logging system to expose |
||||
*/ |
||||
public LoggersEndpoint(LoggingSystem loggingSystem) { |
||||
super("loggers"); |
||||
Assert.notNull(loggingSystem, "LoggingSystem must not be null"); |
||||
this.loggingSystem = loggingSystem; |
||||
} |
||||
|
||||
@Override |
||||
public Map<String, Map<String, String>> invoke() { |
||||
Collection<LoggerConfiguration> loggerConfigurations = this.loggingSystem |
||||
.listLoggerConfigurations(); |
||||
|
||||
if (loggerConfigurations == null) { |
||||
return Collections.emptyMap(); |
||||
} |
||||
|
||||
Map<String, Map<String, String>> result = new LinkedHashMap<String, |
||||
Map<String, String>>(loggerConfigurations.size()); |
||||
|
||||
for (LoggerConfiguration loggerConfiguration : loggerConfigurations) { |
||||
result.put(loggerConfiguration.getName(), result(loggerConfiguration)); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
public Map<String, String> get(String name) { |
||||
Assert.notNull(name, "Name must not be null"); |
||||
return result(this.loggingSystem.getLoggerConfiguration(name)); |
||||
} |
||||
|
||||
public void set(String name, LogLevel level) { |
||||
Assert.notNull(name, "Name must not be empty"); |
||||
this.loggingSystem.setLogLevel(name, level); |
||||
} |
||||
|
||||
private static Map<String, String> result(LoggerConfiguration loggerConfiguration) { |
||||
if (loggerConfiguration == null) { |
||||
return Collections.emptyMap(); |
||||
} |
||||
Map<String, String> result = new LinkedHashMap<String, String>(3); |
||||
LogLevel configuredLevel = loggerConfiguration.getConfiguredLevel(); |
||||
result.put("configuredLevel", |
||||
configuredLevel != null ? configuredLevel.name() : null); |
||||
result.put("effectiveLevel", loggerConfiguration.getEffectiveLevel().name()); |
||||
return result; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
/* |
||||
* Copyright 2016-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.mvc; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.springframework.boot.actuate.endpoint.LoggersEndpoint; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.boot.logging.LogLevel; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.http.ResponseEntity; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PathVariable; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.ResponseBody; |
||||
|
||||
/** |
||||
* Adapter to expose {@link LoggersEndpoint} as an {@link MvcEndpoint}. |
||||
* |
||||
* @author Ben Hale |
||||
* @since 1.5.0 |
||||
*/ |
||||
@ConfigurationProperties(prefix = "endpoints.loggers") |
||||
public class LoggersMvcEndpoint extends EndpointMvcAdapter { |
||||
|
||||
private final LoggersEndpoint delegate; |
||||
|
||||
public LoggersMvcEndpoint(LoggersEndpoint delegate) { |
||||
super(delegate); |
||||
this.delegate = delegate; |
||||
} |
||||
|
||||
@GetMapping(value = "/{name:.*}", produces = MediaType.APPLICATION_JSON_VALUE) |
||||
@ResponseBody |
||||
@HypermediaDisabled |
||||
public Object get(@PathVariable String name) { |
||||
if (!this.delegate.isEnabled()) { |
||||
// Shouldn't happen - MVC endpoint shouldn't be registered when delegate's
|
||||
// disabled
|
||||
return getDisabledResponse(); |
||||
} |
||||
return this.delegate.get(name); |
||||
} |
||||
|
||||
@PostMapping(value = "/{name:.*}", consumes = MediaType.APPLICATION_JSON_VALUE, |
||||
produces = MediaType.APPLICATION_JSON_VALUE) |
||||
@ResponseBody |
||||
@HypermediaDisabled |
||||
public Object set(@PathVariable String name, |
||||
@RequestBody Map<String, String> configuration) { |
||||
if (!this.delegate.isEnabled()) { |
||||
// Shouldn't happen - MVC endpoint shouldn't be registered when delegate's
|
||||
// disabled
|
||||
return getDisabledResponse(); |
||||
} |
||||
String level = configuration.get("configuredLevel"); |
||||
this.delegate.set(name, level == null ? null : LogLevel.valueOf(level)); |
||||
return ResponseEntity.EMPTY; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
/* |
||||
* Copyright 2016-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; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.boot.logging.LogLevel; |
||||
import org.springframework.boot.logging.LoggerConfiguration; |
||||
import org.springframework.boot.logging.LoggingSystem; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.BDDMockito.given; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.verify; |
||||
|
||||
/** |
||||
* Tests for {@link LoggersEndpoint}. |
||||
* |
||||
* @author Ben Hale |
||||
*/ |
||||
public class LoggersEndpointTests extends AbstractEndpointTests<LoggersEndpoint> { |
||||
|
||||
public LoggersEndpointTests() { |
||||
super(Config.class, LoggersEndpoint.class, "loggers", true, "endpoints.loggers"); |
||||
} |
||||
|
||||
@Test |
||||
public void invoke() throws Exception { |
||||
given(getLoggingSystem().listLoggerConfigurations()).willReturn(Collections |
||||
.singleton(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG))); |
||||
Map<String, String> loggingConfiguration = getEndpointBean().invoke() |
||||
.get("ROOT"); |
||||
assertThat(loggingConfiguration.get("configuredLevel")).isNull(); |
||||
assertThat(loggingConfiguration.get("effectiveLevel")).isEqualTo("DEBUG"); |
||||
} |
||||
|
||||
public void get() throws Exception { |
||||
given(getLoggingSystem().getLoggerConfiguration("ROOT")) |
||||
.willReturn(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)); |
||||
Map<String, String> loggingConfiguration = getEndpointBean().get("ROOT"); |
||||
assertThat(loggingConfiguration.get("configuredLevel")).isNull(); |
||||
assertThat(loggingConfiguration.get("effectiveLevel")).isEqualTo("DEBUG"); |
||||
} |
||||
|
||||
public void set() throws Exception { |
||||
getEndpointBean().set("ROOT", LogLevel.DEBUG); |
||||
verify(getLoggingSystem()).setLogLevel("ROOT", LogLevel.DEBUG); |
||||
} |
||||
|
||||
private LoggingSystem getLoggingSystem() { |
||||
return this.context.getBean(LoggingSystem.class); |
||||
} |
||||
|
||||
@Configuration |
||||
@EnableConfigurationProperties |
||||
public static class Config { |
||||
|
||||
@Bean |
||||
public LoggingSystem loggingSystem() { |
||||
return mock(LoggingSystem.class); |
||||
} |
||||
|
||||
@Bean |
||||
public LoggersEndpoint endpoint(LoggingSystem loggingSystem) { |
||||
return new LoggersEndpoint(loggingSystem); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,147 @@
@@ -0,0 +1,147 @@
|
||||
/* |
||||
* Copyright 2016-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.mvc; |
||||
|
||||
import java.util.Collections; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration; |
||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration; |
||||
import org.springframework.boot.actuate.endpoint.LoggersEndpoint; |
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; |
||||
import org.springframework.boot.logging.LogLevel; |
||||
import org.springframework.boot.logging.LoggerConfiguration; |
||||
import org.springframework.boot.logging.LoggingSystem; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.test.context.junit4.SpringRunner; |
||||
import org.springframework.test.web.servlet.MockMvc; |
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders; |
||||
import org.springframework.web.context.WebApplicationContext; |
||||
|
||||
import static org.hamcrest.Matchers.equalTo; |
||||
import static org.mockito.BDDMockito.given; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.verifyZeroInteractions; |
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; |
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; |
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; |
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
||||
/** |
||||
* Tests for {@link LoggersMvcEndpoint}. |
||||
* |
||||
* @author Ben Hale |
||||
*/ |
||||
@RunWith(SpringRunner.class) |
||||
@DirtiesContext |
||||
@SpringBootTest |
||||
public class LoggersMvcEndpointTests { |
||||
|
||||
@Autowired |
||||
private WebApplicationContext context; |
||||
|
||||
@Autowired |
||||
private LoggingSystem loggingSystem; |
||||
|
||||
private MockMvc mvc; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
this.context.getBean(LoggersEndpoint.class).setEnabled(true); |
||||
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); |
||||
} |
||||
|
||||
@Test |
||||
public void list() throws Exception { |
||||
given(this.loggingSystem.listLoggerConfigurations()).willReturn(Collections |
||||
.singleton(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG))); |
||||
|
||||
this.mvc.perform(get("/loggers")).andExpect(status().isOk()) |
||||
.andExpect(content().string(equalTo("{\"ROOT\":{\"configuredLevel\":" |
||||
+ "null,\"effectiveLevel\":\"DEBUG\"}}"))); |
||||
} |
||||
|
||||
@Test |
||||
public void listDisabled() throws Exception { |
||||
this.context.getBean(LoggersEndpoint.class).setEnabled(false); |
||||
this.mvc.perform(get("/loggers")).andExpect(status().isNotFound()); |
||||
} |
||||
|
||||
@Test |
||||
public void getLogger() throws Exception { |
||||
given(this.loggingSystem.getLoggerConfiguration("ROOT")) |
||||
.willReturn(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)); |
||||
|
||||
this.mvc.perform(get("/loggers/ROOT")).andExpect(status().isOk()) |
||||
.andExpect(content().string(equalTo("{\"configuredLevel\":null," |
||||
+ "\"effectiveLevel\":\"DEBUG\"}"))); |
||||
} |
||||
|
||||
@Test |
||||
public void getLoggerDisabled() throws Exception { |
||||
this.context.getBean(LoggersEndpoint.class).setEnabled(false); |
||||
this.mvc.perform(get("/loggers/ROOT")).andExpect(status().isNotFound()); |
||||
} |
||||
|
||||
@Test |
||||
public void setLogger() throws Exception { |
||||
this.mvc.perform(post("/loggers/ROOT").contentType(MediaType.APPLICATION_JSON) |
||||
.content("{\"configuredLevel\":\"DEBUG\"}")).andExpect(status().isOk()); |
||||
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG); |
||||
} |
||||
|
||||
@Test |
||||
public void setLoggerDisabled() throws Exception { |
||||
this.context.getBean(LoggersEndpoint.class).setEnabled(false); |
||||
this.mvc.perform(post("/loggers/ROOT").contentType(MediaType.APPLICATION_JSON) |
||||
.content("{\"configuredLevel\":\"DEBUG\"}")) |
||||
.andExpect(status().isNotFound()); |
||||
verifyZeroInteractions(this.loggingSystem); |
||||
} |
||||
|
||||
@Import({ JacksonAutoConfiguration.class, |
||||
HttpMessageConvertersAutoConfiguration.class, |
||||
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class, |
||||
ManagementServerPropertiesAutoConfiguration.class }) |
||||
@Configuration |
||||
public static class TestConfiguration { |
||||
|
||||
@Bean |
||||
public LoggingSystem loggingSystem() { |
||||
return mock(LoggingSystem.class); |
||||
} |
||||
|
||||
@Bean |
||||
public LoggersEndpoint endpoint(LoggingSystem loggingSystem) { |
||||
return new LoggersEndpoint(loggingSystem); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,111 @@
@@ -0,0 +1,111 @@
|
||||
/* |
||||
* Copyright 2016-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.logging; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* Immutable class that represents the configuration of a {@link LoggingSystem}'s logger. |
||||
* |
||||
* @author Ben Hale |
||||
* @since 1.5.0 |
||||
*/ |
||||
public class LoggerConfiguration { |
||||
|
||||
private final LogLevel configuredLevel; |
||||
|
||||
private final LogLevel effectiveLevel; |
||||
|
||||
private final String name; |
||||
|
||||
/** |
||||
* Create a new {@link LoggerConfiguration instance}. |
||||
* @param name the name of the logger |
||||
* @param configuredLevel the configured level of the logger |
||||
* @param effectiveLevel the effective level of the logger |
||||
*/ |
||||
public LoggerConfiguration(String name, LogLevel configuredLevel, |
||||
LogLevel effectiveLevel) { |
||||
Assert.notNull(name, "Name must not be null"); |
||||
Assert.notNull(effectiveLevel, "EffectiveLevel must not be null"); |
||||
this.name = name; |
||||
this.configuredLevel = configuredLevel; |
||||
this.effectiveLevel = effectiveLevel; |
||||
} |
||||
|
||||
/** |
||||
* Returns the configured level of the logger. |
||||
* @return the configured level of the logger |
||||
*/ |
||||
public LogLevel getConfiguredLevel() { |
||||
return this.configuredLevel; |
||||
} |
||||
|
||||
/** |
||||
* Returns the effective level of the logger. |
||||
* @return the effective level of the logger |
||||
*/ |
||||
public LogLevel getEffectiveLevel() { |
||||
return this.effectiveLevel; |
||||
} |
||||
|
||||
/** |
||||
* Returns the name of the logger. |
||||
* @return the name of the logger |
||||
*/ |
||||
public String getName() { |
||||
return this.name; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return "LoggerConfiguration [name=" + this.name + ", configuredLevel=" |
||||
+ this.configuredLevel + ", effectiveLevel=" + this.effectiveLevel + "]"; |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
final int prime = 31; |
||||
int result = 1; |
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.name); |
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.configuredLevel); |
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.effectiveLevel); |
||||
return result; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null) { |
||||
return false; |
||||
} |
||||
if (obj instanceof LoggerConfiguration) { |
||||
LoggerConfiguration other = (LoggerConfiguration) obj; |
||||
boolean rtn = true; |
||||
rtn &= ObjectUtils.nullSafeEquals(this.name, other.name); |
||||
rtn &= ObjectUtils.nullSafeEquals(this.configuredLevel, |
||||
other.configuredLevel); |
||||
rtn &= ObjectUtils.nullSafeEquals(this.effectiveLevel, other.effectiveLevel); |
||||
return rtn; |
||||
} |
||||
return super.equals(obj); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
/* |
||||
* Copyright 2016-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.logging; |
||||
|
||||
import java.util.Comparator; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* An implementation of {@link Comparator} for comparing {@link LoggerConfiguration}s. |
||||
* Sorts the "root" logger as the first logger and then lexically by name after that. |
||||
* |
||||
* @author Ben Hale |
||||
* @since 1.5.0 |
||||
*/ |
||||
public class LoggerConfigurationComparator implements Comparator<LoggerConfiguration> { |
||||
|
||||
private final String rootLoggerName; |
||||
|
||||
/** |
||||
* Create a new {@link LoggerConfigurationComparator} instance. |
||||
* @param rootLoggerName the name of the "root" logger |
||||
*/ |
||||
public LoggerConfigurationComparator(String rootLoggerName) { |
||||
Assert.notNull(rootLoggerName, "RootLoggerName must not be null"); |
||||
this.rootLoggerName = rootLoggerName; |
||||
} |
||||
|
||||
@Override |
||||
public int compare(LoggerConfiguration o1, LoggerConfiguration o2) { |
||||
if (this.rootLoggerName.equals(o1.getName())) { |
||||
return -1; |
||||
} |
||||
|
||||
if (this.rootLoggerName.equals(o2.getName())) { |
||||
return 1; |
||||
} |
||||
|
||||
return o1.getName().compareTo(o2.getName()); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
/* |
||||
* Copyright 2016-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.logging; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link LoggerConfigurationComparator}. |
||||
* |
||||
* @author Ben Hale |
||||
*/ |
||||
public class LoggerConfigurationComparatorTests { |
||||
|
||||
private final LoggerConfigurationComparator comparator = |
||||
new LoggerConfigurationComparator("ROOT"); |
||||
|
||||
@Test |
||||
public void rootLoggerFirst() { |
||||
LoggerConfiguration first = new LoggerConfiguration("ROOT", null, LogLevel.OFF); |
||||
LoggerConfiguration second = new LoggerConfiguration("alpha", null, LogLevel.OFF); |
||||
assertThat(this.comparator.compare(first, second)).isLessThan(0); |
||||
} |
||||
|
||||
@Test |
||||
public void rootLoggerSecond() { |
||||
LoggerConfiguration first = new LoggerConfiguration("alpha", null, LogLevel.OFF); |
||||
LoggerConfiguration second = new LoggerConfiguration("ROOT", null, LogLevel.OFF); |
||||
assertThat(this.comparator.compare(first, second)).isGreaterThan(0); |
||||
} |
||||
|
||||
@Test |
||||
public void rootLoggerFirstEmpty() { |
||||
LoggerConfiguration first = new LoggerConfiguration("ROOT", null, LogLevel.OFF); |
||||
LoggerConfiguration second = new LoggerConfiguration("", null, LogLevel.OFF); |
||||
assertThat(this.comparator.compare(first, second)).isLessThan(0); |
||||
} |
||||
|
||||
@Test |
||||
public void rootLoggerSecondEmpty() { |
||||
LoggerConfiguration first = new LoggerConfiguration("", null, LogLevel.OFF); |
||||
LoggerConfiguration second = new LoggerConfiguration("ROOT", null, LogLevel.OFF); |
||||
assertThat(this.comparator.compare(first, second)).isGreaterThan(0); |
||||
} |
||||
|
||||
@Test |
||||
public void lexicalFirst() { |
||||
LoggerConfiguration first = new LoggerConfiguration("alpha", null, LogLevel.OFF); |
||||
LoggerConfiguration second = new LoggerConfiguration("bravo", null, LogLevel.OFF); |
||||
assertThat(this.comparator.compare(first, second)).isLessThan(0); |
||||
} |
||||
|
||||
@Test |
||||
public void lexicalSecond() { |
||||
LoggerConfiguration first = new LoggerConfiguration("bravo", null, LogLevel.OFF); |
||||
LoggerConfiguration second = new LoggerConfiguration("alpha", null, LogLevel.OFF); |
||||
assertThat(this.comparator.compare(first, second)).isGreaterThan(0); |
||||
} |
||||
|
||||
@Test |
||||
public void lexicalEqual() { |
||||
LoggerConfiguration first = new LoggerConfiguration("alpha", null, LogLevel.OFF); |
||||
LoggerConfiguration second = new LoggerConfiguration("alpha", null, LogLevel.OFF); |
||||
assertThat(this.comparator.compare(first, second)).isEqualTo(0); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue