Skip to content

Commit 59437df

Browse files
committed
Add support for configuring logging via JMX
1 parent e34c2b0 commit 59437df

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-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;
@@ -55,6 +62,7 @@
5562
* @author Dave Syer
5663
* @author Andy Wilkinson
5764
* @author Ben Hale
65+
* @author Vedran Pavic
5866
*/
5967
public class LogbackLoggingSystem extends Slf4JLoggingSystem {
6068

@@ -125,6 +133,7 @@ protected void loadDefaults(LoggingInitializationContext initializationContext,
125133
LogFile logFile) {
126134
LoggerContext context = getLoggerContext();
127135
stopAndReset(context);
136+
registerJmxConfigurator(context, initializationContext, null, logFile);
128137
LogbackConfigurator configurator = new LogbackConfigurator(context);
129138
Environment environment = initializationContext.getEnvironment();
130139
context.putProperty("LOG_LEVEL_PATTERN", environment.resolvePlaceholders(
@@ -142,6 +151,7 @@ protected void loadConfiguration(LoggingInitializationContext initializationCont
142151
super.loadConfiguration(initializationContext, location, logFile);
143152
LoggerContext loggerContext = getLoggerContext();
144153
stopAndReset(loggerContext);
154+
registerJmxConfigurator(loggerContext, initializationContext, location, logFile);
145155
try {
146156
configureByResourceUrl(initializationContext, loggerContext,
147157
ResourceUtils.getURL(location));
@@ -193,6 +203,28 @@ private void addLevelChangePropagator(LoggerContext loggerContext) {
193203
loggerContext.addListener(levelChangePropagator);
194204
}
195205

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

315347
}
316348

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

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

Lines changed: 5 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;
@@ -136,6 +139,8 @@ public void withFile() throws Exception {
136139
public void testBasicConfigLocation() throws Exception {
137140
this.loggingSystem.beforeInitialize();
138141
assertThat(getConsoleAppender()).isNotNull();
142+
assertThat(ManagementFactory.getPlatformMBeanServer().queryMBeans(
143+
new ObjectName("ch.qos.logback.classic:Name=default,*"), null)).hasSize(1);
139144
}
140145

141146
@Test

0 commit comments

Comments
 (0)