Skip to content

Commit d1272f0

Browse files
committed
Add support for configuring logging via JMX
1 parent b2839e2 commit d1272f0

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,22 @@
1616

1717
package org.springframework.boot.logging.logback;
1818

19+
import java.io.FileNotFoundException;
20+
import java.lang.management.ManagementFactory;
1921
import java.net.URL;
2022
import java.security.CodeSource;
2123
import java.security.ProtectionDomain;
2224
import java.util.ArrayList;
2325
import java.util.List;
2426
import java.util.Set;
2527

28+
import javax.management.MBeanServer;
29+
import javax.management.ObjectName;
30+
2631
import ch.qos.logback.classic.Level;
2732
import ch.qos.logback.classic.LoggerContext;
33+
import ch.qos.logback.classic.jmx.JMXConfigurator;
34+
import ch.qos.logback.classic.jmx.MBeanUtil;
2835
import ch.qos.logback.classic.joran.JoranConfigurator;
2936
import ch.qos.logback.classic.jul.LevelChangePropagator;
3037
import ch.qos.logback.classic.turbo.TurboFilter;
@@ -54,6 +61,7 @@
5461
* @author Dave Syer
5562
* @author Andy Wilkinson
5663
* @author Ben Hale
64+
* @author Vedran Pavic
5765
*/
5866
public class LogbackLoggingSystem extends Slf4JLoggingSystem {
5967

@@ -124,6 +132,7 @@ protected void loadDefaults(LoggingInitializationContext initializationContext,
124132
LogFile logFile) {
125133
LoggerContext context = getLoggerContext();
126134
stopAndReset(context);
135+
registerJmxConfigurator(context, initializationContext, null, logFile);
127136
LogbackConfigurator configurator = new LogbackConfigurator(context);
128137
context.putProperty("LOG_LEVEL_PATTERN",
129138
initializationContext.getEnvironment().resolvePlaceholders(
@@ -139,6 +148,7 @@ protected void loadConfiguration(LoggingInitializationContext initializationCont
139148
super.loadConfiguration(initializationContext, location, logFile);
140149
LoggerContext loggerContext = getLoggerContext();
141150
stopAndReset(loggerContext);
151+
registerJmxConfigurator(loggerContext, initializationContext, location, logFile);
142152
try {
143153
configureByResourceUrl(initializationContext, loggerContext,
144154
ResourceUtils.getURL(location));
@@ -190,6 +200,28 @@ private void addLevelChangePropagator(LoggerContext loggerContext) {
190200
loggerContext.addListener(levelChangePropagator);
191201
}
192202

203+
private void registerJmxConfigurator(LoggerContext loggerContext,
204+
LoggingInitializationContext initializationContext, String configLocation,
205+
LogFile logFile) {
206+
String objectNameAsStr = MBeanUtil.getObjectNameFor(
207+
loggerContext.getName(), JMXConfigurator.class);
208+
ObjectName objectName = MBeanUtil.string2ObjectName(
209+
loggerContext, this, objectNameAsStr);
210+
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
211+
if (!MBeanUtil.isRegistered(mbs, objectName)) {
212+
LoggingSystemJMXConfigurator jmxConfigurator =
213+
new LoggingSystemJMXConfigurator(loggerContext, mbs, objectName,
214+
initializationContext, configLocation, logFile);
215+
try {
216+
mbs.registerMBean(jmxConfigurator, objectName);
217+
}
218+
catch (Exception e) {
219+
getLogger(LogbackLoggingSystem.class.getName()).error(
220+
"Failed to create mbean", e);
221+
}
222+
}
223+
}
224+
193225
@Override
194226
public void cleanUp() {
195227
LoggerContext context = getLoggerContext();
@@ -311,4 +343,34 @@ public void run() {
311343

312344
}
313345

346+
private class LoggingSystemJMXConfigurator extends JMXConfigurator {
347+
348+
private LoggingInitializationContext initializationContext;
349+
350+
private String configLocation;
351+
352+
private LogFile logFile;
353+
354+
LoggingSystemJMXConfigurator(LoggerContext loggerContext, MBeanServer mbs,
355+
ObjectName objectName, LoggingInitializationContext initializationContext,
356+
String configLocation, LogFile logFile) {
357+
super(loggerContext, mbs, objectName);
358+
this.initializationContext = initializationContext;
359+
this.configLocation = configLocation;
360+
this.logFile = logFile;
361+
}
362+
363+
@Override
364+
public void reloadDefaultConfiguration() throws JoranException {
365+
initialize(this.initializationContext, this.configLocation, this.logFile);
366+
}
367+
368+
@Override
369+
public void reloadByFileName(String fileName)
370+
throws JoranException, FileNotFoundException {
371+
initialize(this.initializationContext, fileName, this.logFile);
372+
}
373+
374+
}
375+
314376
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818

1919
import java.io.File;
2020
import java.io.FileReader;
21+
import java.lang.management.ManagementFactory;
2122
import java.util.EnumSet;
2223
import java.util.List;
2324
import java.util.logging.Handler;
2425
import java.util.logging.LogManager;
2526

27+
import javax.management.ObjectName;
28+
2629
import ch.qos.logback.classic.Level;
2730
import ch.qos.logback.classic.Logger;
2831
import ch.qos.logback.classic.LoggerContext;
@@ -66,6 +69,7 @@
6669
* @author Andy Wilkinson
6770
* @author Ben Hale
6871
* @author Madhura Bhave
72+
* @author Vedran Pavic
6973
*/
7074
public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
7175

@@ -129,6 +133,8 @@ public void testBasicConfigLocation() throws Exception {
129133
LoggerContext context = (LoggerContext) factory;
130134
Logger root = context.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
131135
assertThat(root.getAppender("CONSOLE")).isNotNull();
136+
assertThat(ManagementFactory.getPlatformMBeanServer().queryMBeans(
137+
new ObjectName("ch.qos.logback.classic:Name=default,*"), null)).hasSize(1);
132138
}
133139

134140
@Test

0 commit comments

Comments
 (0)