4

I know how to set the log level via environment variables and application properties.

Is there a way to set them programmatically?

I would like to set log levels for particular test classes (which are using SpringJUnit4ClassRunner and @SpringApplicationConfiguration), but not all of them, and without having a separate properties file for every combination.

I tried defining a non-lazy bean to add a new PropertySource to the environment; the method was called but it had no effect.

@Bean
@Lazy(false)
public PropertySource testProperties(ConfigurableEnvironment environment) {
  PropertySource properties = new MapPropertySource("testProperties", Collections.singletonMap(
      "logging.level.org.springframework.security", "DEBUG"
  ));

  environment.getPropertySources().addFirst(properties);
  return properties;
}
Community
  • 1
  • 1
OrangeDog
  • 36,653
  • 12
  • 122
  • 207

2 Answers2

5

You can use @TestPropertySource on your test classes. Unlike the bean-based approach that you tried, @TestPropertySource will add the property source to the environment before the context starts which allows the properties to be picked up when the logging system is initialized.

Something like this:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(YourApplication.class)
@TestPropertySource(properties = "logging.level.org.springframework.security:DEBUG")
public class YourApplicationTests {
    // …
}
Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • this didnt work for me, I am creating a spring boot library which does not have main springboot application and therefore everything has to be loaded from test class. and somehow I am not able to disable/change logging – Manish Bansal Aug 06 '19 at 16:56
1

Credit to Boris the Spider for the hints.

First, add an element <jmxConfigurator /> to the logback.xml.

Then, this code will work:

@Before
public void configureLogging() throws JMException {
    ObjectName name = new ObjectName(String.format("ch.qos.logback.classic:Name=default,Type=%s", JMXConfigurator.class.getName()));
    JMXConfiguratorMBean logbackMBean = JMX.newMBeanProxy(ManagementFactory.getPlatformMBeanServer(), name, JMXConfiguratorMBean.class);
    logbackMBean.setLoggerLevel("org.springframework.security", "DEBUG");
}

Sadly, there doesn't appear to be a better way to build the object name: the Package hierarchy isn't traversable and the string "default" isn't accessible anywhere I can find.

Community
  • 1
  • 1
OrangeDog
  • 36,653
  • 12
  • 122
  • 207