Skip to content

Commit 7cd0103

Browse files
committed
Add support for configuring logging via JMX
1 parent 270acd4 commit 7cd0103

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed

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

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,15 +16,21 @@
1616

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

19+
import java.lang.management.ManagementFactory;
1920
import java.net.URL;
2021
import java.security.CodeSource;
2122
import java.security.ProtectionDomain;
2223
import java.util.ArrayList;
2324
import java.util.List;
2425
import java.util.Set;
2526

27+
import javax.management.MBeanServer;
28+
import javax.management.ObjectName;
29+
2630
import ch.qos.logback.classic.Level;
2731
import ch.qos.logback.classic.LoggerContext;
32+
import ch.qos.logback.classic.jmx.JMXConfigurator;
33+
import ch.qos.logback.classic.jmx.MBeanUtil;
2834
import ch.qos.logback.classic.joran.JoranConfigurator;
2935
import ch.qos.logback.classic.jul.LevelChangePropagator;
3036
import ch.qos.logback.classic.turbo.TurboFilter;
@@ -56,6 +62,7 @@
5662
* @author Dave Syer
5763
* @author Andy Wilkinson
5864
* @author Ben Hale
65+
* @author Vedran Pavic
5966
*/
6067
public class LogbackLoggingSystem extends Slf4JLoggingSystem {
6168

@@ -126,6 +133,7 @@ protected void loadDefaults(LoggingInitializationContext initializationContext,
126133
LogFile logFile) {
127134
LoggerContext context = getLoggerContext();
128135
stopAndReset(context);
136+
registerJmxConfigurator(context, initializationContext, null, logFile);
129137
LogbackConfigurator configurator = new LogbackConfigurator(context);
130138
Environment environment = initializationContext.getEnvironment();
131139
context.putProperty(LoggingSystemProperties.LOG_LEVEL_PATTERN,
@@ -145,6 +153,7 @@ protected void loadConfiguration(LoggingInitializationContext initializationCont
145153
super.loadConfiguration(initializationContext, location, logFile);
146154
LoggerContext loggerContext = getLoggerContext();
147155
stopAndReset(loggerContext);
156+
registerJmxConfigurator(loggerContext, initializationContext, location, logFile);
148157
try {
149158
configureByResourceUrl(initializationContext, loggerContext,
150159
ResourceUtils.getURL(location));
@@ -196,6 +205,28 @@ private void addLevelChangePropagator(LoggerContext loggerContext) {
196205
loggerContext.addListener(levelChangePropagator);
197206
}
198207

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

318349
}
319350

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

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -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;
@@ -487,6 +490,24 @@ public void testDateformatPatternProperty() {
487490
.containsPattern("\\d{4}-\\d{2}\\-\\d{2}T\\d{2}:\\d{2}:\\d{2}");
488491
}
489492

493+
@Test
494+
public void testDefaultJmxConfigurator() throws Exception {
495+
this.loggingSystem.beforeInitialize();
496+
assertThat(ManagementFactory.getPlatformMBeanServer().queryMBeans(
497+
new ObjectName("ch.qos.logback.classic:Name=default,*"), null))
498+
.hasSize(1);
499+
}
500+
501+
@Test
502+
public void testExplicitJmxConfigurator() throws Exception {
503+
this.loggingSystem.beforeInitialize();
504+
this.loggingSystem.initialize(this.initializationContext,
505+
"classpath:logback-jmxconfigurator.xml", null);
506+
assertThat(ManagementFactory.getPlatformMBeanServer().queryMBeans(
507+
new ObjectName("ch.qos.logback.classic:Name=default,*"), null))
508+
.hasSize(1);
509+
}
510+
490511
private static Logger getRootLogger() {
491512
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
492513
LoggerContext context = (LoggerContext) factory;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<configuration>
3+
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
4+
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
5+
<jmxConfigurator/>
6+
</configuration>

0 commit comments

Comments
 (0)